Wie verwende ich den Befehl 'cp', um ein bestimmtes Verzeichnis auszuschließen?
409
Ich möchte alle Dateien in einem Verzeichnis kopieren, mit Ausnahme einiger Dateien in einem bestimmten Unterverzeichnis. Ich habe festgestellt, dass der Befehl 'cp' keine Option --exclude hatte. Wie kann ich das erreichen?
Beachten Sie, dass die Option dir thefoldertoexcludeafter --excluderelativ zu sourcefolder, dh , sourcefolder/thefoldertoexclude.
Sie können auch einen -nTrockenlauf hinzufügen, um zu sehen, was kopiert wird, bevor der eigentliche Vorgang ausgeführt wird. Wenn alles in Ordnung ist, entfernen Sie ihn -naus der Befehlszeile.
Einverstanden, Sie können die Einfachheit und Kraft von--exclude
Matthew Wilcoxson
31
ist das thefoldertoexcluderelativ zum sourcefolderoder dem aktuellen Arbeitsverzeichnis? danke
Beebee
45
Es ist relativ zum Quellordner. Dadurch wird die Ordnerquelle / .git vom Kopieren ausgeschlossen. rsync -r --exclude '.git' Quellziel
orkoden
15
Vielleicht irre ich mich, aber ich denke, es ist eine gute Praxis, "Schalter" vor "Parameter" hinzuzufügen. Auch die Manpage von rsync-Berichten - Ausschluss verwendbar wie mit der Syntax "=" oder ohne. Um sich betriebssystemübergreifend zu standardisieren, würde ich rsync -av --progress --exclude="thefoldertoexclude" sourcefolder /destinationfolder- ohnehin upvote für den rsync anstelle des find - verwenden, da Sie leicht absolute Pfade für die Quelle verwenden können, während es im find schwieriger ist, als {}im dst.
Xavi Montero
1
@mamun Natürlich zB vom Remote-Server zum lokalen Computer: $ rsync [email protected]:/var/www/mypage /var/www/mylocalpage/oder vom lokalen zum Remote- $ rsync /var/www/mylocalpage/ [email protected]:/var/www/mypage
Computer
84
Nun, wenn das Ausschließen bestimmter Dateinamenmuster von jedem Unix-ish-Dateidienstprogramm (wie cp, mv, rm, tar, rsync, scp, ...) durchgeführt werden müsste, würde eine immense Doppelarbeit auftreten. Stattdessen können solche Dinge als Teil des Globbings ausgeführt werden , dh durch Ihre Shell.
Sie fügen also einfach ein Muster ein !()und es negiert die Übereinstimmung. Das Muster kann beliebig komplex sein, angefangen bei der Aufzählung einzelner Pfade (wie Vanwaril in einer anderen Antwort zeigt) !(filename1|path2|etc3)bis hin zu regexartigen Dingen mit Sternen und Zeichenklassen. Weitere Informationen finden Sie in der Manpage.
@MikhailGolubtsov Vielleicht liegt das daran, dass Globbing nicht rekursiv ist und eine Ebene nach der anderen funktioniert. Herausgeschnitten. PS: Es funktioniert aber in zsh.
Ulidtko
3
Netter Pro-Tipp! Auf diese Weise können Sie einzelne Elemente einfach entfernen. Vielen Dank!
Taft
Übrigens, um erweiterte Mustervergleichsfunktionen in Bash zu deaktivieren, führen Sie aus setopt -u extglob.
Rockallite
49
Warum verwenden, rsyncwenn Sie Folgendes tun können:
Ich denke, Sie brauchen das -pathArgument, um Pfadhierarchien zu testen, nicht -iname
James Murty
3
Und Sie brauchen auch ein Semikolon am Ende:find . -type f -not -path '*/not-from-here/*' -exec cp '{}' '/dest/{}' \;
Matthew Wilcoxson
1
Wow, es lässt mich nicht: "Bearbeitungen müssen mindestens 6 Zeichen sein"!
Matthew Wilcoxson
1
@ MatthewWilcoxson Meh. Diese Einschränkungen werden aufgehoben, sobald Sie etwas mehr Wiederholungen erhalten. Ich habe die Antwort entsprechend bearbeitet. Danke noch einmal!
Linus Kleen
1
@ Henning warum nicht rsync? Weil es möglicherweise nicht im System vorhanden ist! während find, cpist immer auf ihren Plätzen. Oder Sie von Leuten, die 2 Gig-Sachen installiert haben, um einfache Dinge zu tun?
Eine Shell-Funktion wurde erstellt, die die Verwendung für den benutzerdefinierten # $1 = source path # $2 = destination path # $3 = filter copy_from_source_to_destination_except_filter() { cp -r $(ls -A $1 | grep -v -w $3 | awk -v path=$1 '{printf "%s/%s ", path, $1}') $2 }
Quellpfad
schlägt mit Verzeichnissen mit Leerzeichen fehl
Sérgio
27
Der einfachste Weg, den ich gefunden habe, bei dem Sie alle Dateien außer Dateien und Ordnern kopieren können, indem Sie ihre Namen in Klammern einfügen:
Sie können das Extra überspringen lsund einfach tun cp !(file1|file1) dest.
Shawn Chin
Verwenden Sie nicht -laR. Es wird eine Zeichenfolge hinzugefügt, die cp stört. cp $(ls folder/!exclude_folder0|exclude_folder1)) dest
LAL
5
Eine weitere einfachere Option ist die Installation und Verwendung von rsync mit der Option --exclude-dir, das sowohl für lokale als auch für entfernte Dateien verwendet werden kann.
rsyncist eigentlich ziemlich knifflig. müssen mehrere Tests durchführen, damit es funktioniert.
Angenommen, Sie kopieren möchten /var/www/htmlzu /var/www/devmüssen aber ausschließen/var/www/html/site/video/ vielleicht Verzeichnis aufgrund seiner Größe. Der Befehl wäre:
Der letzte Schrägstrich /in der Quelle wird benötigt, andernfalls wird auch das Quellverzeichnis anstelle seines Inhalts kopiert und wird/var/www/dev/html/xxxx , was möglicherweise nicht das ist, was Sie wollen.
Der --excludePfad ist direkt relativ zur Quelle. Selbst wenn Sie den vollständigen absoluten Pfad angeben, funktioniert dies nicht.
-vist für ausführlich, -aist für den Archivierungsmodus, was bedeutet, dass Sie eine Rekursion wünschen und fast alles beibehalten möchten.
Achten Sie auf Verzeichniseinträge mit Leerzeichen.
Paulo Scardine
3
Dies ist eine Modifikation von Linus Kleens Antwort. Seine Antwort hat bei mir nicht funktioniert, weil es eine geben würde. vor dem Dateipfad hinzugefügt, den cp nicht mag (der Pfad würde wie source / .destination / file aussehen).
Vielleicht nicht schön - aber dies ist die einzige Option, die ich hier gefunden habe und die mit cpeiner Standard-POSIX-Shell funktioniert sh.
Tomekwi
0
Ich benutze eine "do while" -Schleife, um die Ausgabe des Befehls find zu lesen. In diesem Beispiel stimme ich mit bestimmten Mustern überein (anstatt sie auszuschließen), da es eine begrenzte Anzahl von Musterübereinstimmungen gibt, die ich möchte, als die ich nicht möchte. Sie können die Logik mit einem -not vor den -iname-Flags umkehren:
Ich verwende das oben Gesagte, um alle Musiktypdateien zu kopieren, die auf meinem Server neuer sind als die Dateien auf einem Western Digital TV Live Hub, den ich unter / media / wd gemountet habe. Ich benutze das oben genannte, weil ich viele DVD-Dateien, MPEGs usw. habe, die ich ausschließen möchte UND weil rsync aus irgendeinem Grund so aussieht, als würde es kopiert, aber nachdem ich mir das wd-Gerät angesehen habe, sind die Dateien trotz nein nicht da Fehler während der Rsync mit diesem Befehl:
Der erste Teil lsalle Dateien aber versteckte bestimmte Dateien mit Flag -I. Die Ausgabe von lswird als Standardeingabe für den zweiten Teil verwendet. xargsBefehl cp -rf -t destdiraus Standardeingabe erstellen und ausführen . die Flag - -rMittel kopieren Verzeichnisse rekursiv, -fmittels Kopieren von Dateien mit Gewalt , welche die Dateien in die überschrieben werden destdir, -tum das Zielverzeichnis kopieren angeben.
tar -c | tar -x
?Antworten:
rsync ist schnell und einfach:
Sie können
--exclude
mehrere Male verwenden.Beachten Sie, dass die Option dir
thefoldertoexclude
after--exclude
relativ zusourcefolder
, dh ,sourcefolder/thefoldertoexclude
.Sie können auch einen
-n
Trockenlauf hinzufügen, um zu sehen, was kopiert wird, bevor der eigentliche Vorgang ausgeführt wird. Wenn alles in Ordnung ist, entfernen Sie ihn-n
aus der Befehlszeile.quelle
--exclude
thefoldertoexclude
relativ zumsourcefolder
oder dem aktuellen Arbeitsverzeichnis? dankersync -av --progress --exclude="thefoldertoexclude" sourcefolder /destinationfolder
- ohnehin upvote für den rsync anstelle des find - verwenden, da Sie leicht absolute Pfade für die Quelle verwenden können, während es im find schwieriger ist, als{}
im dst.$ rsync [email protected]:/var/www/mypage /var/www/mylocalpage/
oder vom lokalen zum Remote-$ rsync /var/www/mylocalpage/ [email protected]:/var/www/mypage
Nun, wenn das Ausschließen bestimmter Dateinamenmuster von jedem Unix-ish-Dateidienstprogramm (wie cp, mv, rm, tar, rsync, scp, ...) durchgeführt werden müsste, würde eine immense Doppelarbeit auftreten. Stattdessen können solche Dinge als Teil des Globbings ausgeführt werden , dh durch Ihre Shell.
Bash
man 1 bash
, / extglob .Beispiel:
Sie fügen also einfach ein Muster ein
!()
und es negiert die Übereinstimmung. Das Muster kann beliebig komplex sein, angefangen bei der Aufzählung einzelner Pfade (wie Vanwaril in einer anderen Antwort zeigt)!(filename1|path2|etc3)
bis hin zu regexartigen Dingen mit Sternen und Zeichenklassen. Weitere Informationen finden Sie in der Manpage.zsh
man 1 zshexpn
, / Dateinamengenerierung .Sie können
setopt KSH_GLOB
bashartige Muster erstellen und verwenden. Oder,Entspricht also dem
x~y
Musterx
, schließt jedoch das Muster ausy
. Weitere Informationen finden Sie auf der Manpage.Fisch neu!
Die Fischschale hat eine viel schönere Antwort darauf:
Bonus Pro-Tipp
Tippen Sie
cp *
, drücken Sie CtrlX*und sehen Sie, was passiert. Es ist nicht schädlich, das verspreche ichquelle
zsh
.setopt -u extglob
.Warum verwenden,
rsync
wenn Sie Folgendes tun können:Dies setzt voraus, dass die Zielverzeichnisstruktur mit der der Quelle übereinstimmt.
quelle
-path
Argument, um Pfadhierarchien zu testen, nicht -inamefind . -type f -not -path '*/not-from-here/*' -exec cp '{}' '/dest/{}' \;
rsync
? Weil es möglicherweise nicht im System vorhanden ist! währendfind
,cp
ist immer auf ihren Plätzen. Oder Sie von Leuten, die 2 Gig-Sachen installiert haben, um einfache Dinge zu tun?quelle
# $1 = source path # $2 = destination path # $3 = filter copy_from_source_to_destination_except_filter() { cp -r $(ls -A $1 | grep -v -w $3 | awk -v path=$1 '{printf "%s/%s ", path, $1}') $2 }
Der einfachste Weg, den ich gefunden habe, bei dem Sie alle Dateien außer Dateien und Ordnern kopieren können, indem Sie ihre Namen in Klammern einfügen:
quelle
-bash: !: event not found
Dies erweitert den Kommentar von mvds und funktioniert für mich
quelle
Es ist relativ zum Quellverzeichnis.
Dadurch wird das Verzeichnis
source/.git
vom Kopieren ausgeschlossen.quelle
rsync
und versuchen Sie es zuerst mit der Option -n, um zu sehen, was kopiert werden soll
quelle
Ich nehme an, Sie verwenden Bash oder Dash. Würde das funktionieren?
Führen Sie ein ls aus, ohne die Dateien auszuschließen, die Sie nicht möchten, und verwenden Sie dies als erstes Argument für cp
quelle
ls
und einfach tuncp !(file1|file1) dest
.cp $(ls folder/!exclude_folder0|exclude_folder1)) dest
Eine weitere einfachere Option ist die Installation und Verwendung von rsync mit der Option --exclude-dir, das sowohl für lokale als auch für entfernte Dateien verwendet werden kann.
quelle
rsync
ist eigentlich ziemlich knifflig. müssen mehrere Tests durchführen, damit es funktioniert.Angenommen, Sie kopieren möchten
/var/www/html
zu/var/www/dev
müssen aber ausschließen/var/www/html/site/video/
vielleicht Verzeichnis aufgrund seiner Größe. Der Befehl wäre:rsync -av --exclude 'sites/video' /var/www/html/ /var/www/dev
Einige Einschränkungen :
/
in der Quelle wird benötigt, andernfalls wird auch das Quellverzeichnis anstelle seines Inhalts kopiert und wird/var/www/dev/html/xxxx
, was möglicherweise nicht das ist, was Sie wollen.Der
--exclude
Pfad ist direkt relativ zur Quelle. Selbst wenn Sie den vollständigen absoluten Pfad angeben, funktioniert dies nicht.-v
ist für ausführlich,-a
ist für den Archivierungsmodus, was bedeutet, dass Sie eine Rekursion wünschen und fast alles beibehalten möchten.quelle
Bearbeiten: Ich habe vergessen, auch den Zielpfad auszuschließen (andernfalls würde er rekursiv kopiert).
quelle
Dies ist eine Modifikation von Linus Kleens Antwort. Seine Antwort hat bei mir nicht funktioniert, weil es eine geben würde. vor dem Dateipfad hinzugefügt, den cp nicht mag (der Pfad würde wie source / .destination / file aussehen).
Dieser Befehl hat bei mir funktioniert:
find . -type f -not -path '*/exlude-path/*' -exec cp --parents '{}' '/destination/' \;
Der Befehl --parents behält die Verzeichnisstruktur bei.
quelle
quelle
Verschieben Sie es einfach vorübergehend in ein verstecktes Verzeichnis (und benennen Sie es anschließend um, falls gewünscht).
quelle
cp
einer Standard-POSIX-Shell funktioniertsh
.Ich benutze eine "do while" -Schleife, um die Ausgabe des Befehls find zu lesen. In diesem Beispiel stimme ich mit bestimmten Mustern überein (anstatt sie auszuschließen), da es eine begrenzte Anzahl von Musterübereinstimmungen gibt, die ich möchte, als die ich nicht möchte. Sie können die Logik mit einem -not vor den -iname-Flags umkehren:
Ich verwende das oben Gesagte, um alle Musiktypdateien zu kopieren, die auf meinem Server neuer sind als die Dateien auf einem Western Digital TV Live Hub, den ich unter / media / wd gemountet habe. Ich benutze das oben genannte, weil ich viele DVD-Dateien, MPEGs usw. habe, die ich ausschließen möchte UND weil rsync aus irgendeinem Grund so aussieht, als würde es kopiert, aber nachdem ich mir das wd-Gerät angesehen habe, sind die Dateien trotz nein nicht da Fehler während der Rsync mit diesem Befehl:
quelle
Der erste Teil
ls
alle Dateien aber versteckte bestimmte Dateien mit Flag-I
. Die Ausgabe vonls
wird als Standardeingabe für den zweiten Teil verwendet.xargs
Befehlcp -rf -t destdir
aus Standardeingabe erstellen und ausführen . die Flag --r
Mittel kopieren Verzeichnisse rekursiv,-f
mittels Kopieren von Dateien mit Gewalt , welche die Dateien in die überschrieben werdendestdir
,-t
um das Zielverzeichnis kopieren angeben.quelle
cp -r
ls -A | grep -v "Excluded_File_or_folder"
../$target_location -vquelle