BASH kopiert alle Dateien bis auf eine

109

Ich möchte alle Dateien aus einem Verzeichnis kopieren, mit Ausnahme eines mit dem Namen Default.png. Es scheint, dass es eine Reihe von Möglichkeiten gibt, dies zu tun. Was scheint Ihnen am effektivsten zu sein?

Joe Cannatti
quelle
Warum brauchen Sie es, um diese Datei zu überspringen, anstatt sie nur nach dem Kopieren zu löschen? Existiert es bereits im Zielverzeichnis?
Lasse V. Karlsen
1
Ja, eine Datei mit demselben Namen befindet sich bereits im Zielverzeichnis.
Joe Cannatti
@ LasseV.Karlsen: Oder Sie möchten die Zeit zum Kopieren sparen, wenn es sich um eine große Datei handelt. Ich bin daran interessiert, schließe aber eher ein Verzeichnis als eine Datei aus.
Nikana Reklawyks

Antworten:

54

Einfach, wenn src/nur Dateien enthalten:

find src/ ! -name Default.png -exec cp -t dest/ {} +

Wenn src/Unterverzeichnisse vorhanden sind, werden diese weggelassen, es werden jedoch Dateien in diese kopiert:

find src/ -type f ! -name Default.png -exec cp -t dest/ {} +

Wenn src/Unterverzeichnisse vorhanden sind, wird dies nicht wiederholt:

find src/ -type f -maxdepth 1 ! -name Default.png -exec cp -t dest/ {} +
John Kugelman
quelle
5
Dies stellt sich für mich als das Beste heraus, da OS X anscheinend ohne Glob aktiviert ist.
Joe Cannatti
6
@Max \;führt den Befehl einmal pro Datei aus. +führt den Befehl einmal aus und übergibt ihm alle Dateinamen auf einmal (vorbehaltlich der Beschränkung der Befehlszeilenlänge). +ist im Allgemeinen etwas effizienter.
John Kugelman
147

Sollte wie folgt sein:

cp -r !(Default.png) /dest

Wenn Sie in einen Ordner kopieren, der im aktuellen Ordner verschachtelt ist (im folgenden Fall als Beispiel bezeichnet), müssen Sie dieses Verzeichnis auch weglassen:

cp -r !(Default.png|example) /example
Jon
quelle
16
Dies erzeugt -bash:!: Ereignis nicht gefunden
Joe Cannatti
Kopieren Sie die Dateien in einen Ordner, der in dem Ordner verschachtelt ist, aus dem Sie kopieren?
Jon
46
Dies muss shopt -s extglobfunktionieren, wenn es deaktiviert wurde.
Barry Kelly
5
Es scheint, dass OS X shopt -s extglobwie von @BarryKelly beschrieben verwendet werden muss. Damit funktioniert es perfekt.
Kat
Jahre auf Bash und wusste nicht über !()... Schön! Für diejenigen, die - wie ich - der Meinung sind, dass es Zeit ist, Bash zu studieren / zu überprüfen , sind hier die relevanten Links zu dieser Frage / Antwort: shopt / extglob und das Muster .
Brandt
73

rsync ist seit langem mein cp / scp ersatz:

rsync -av from/ to/ --exclude=Default.png

-a, --archive               archive mode; equals -rlptgoD (no -H,-A,-X)
-v, --verbose               increase verbosity
Matja
quelle
Wie verwende ich diese Datei, wenn ich zwei verschiedene Dateien ausschließen möchte?
Pulkit Bansal
multiple --exclude = Argumente werden unterstützt. Und vergessen -rSie nicht das Argument, wenn Sie Verzeichnisse synchronisieren
Rian Sanderson
5

Ich würde einfach tun:

cp srcdir/* destdir/ ; rm destdir/Default.png

es sei denn, die Dateien sind groß. Ansonsten zB verwenden

find srcdir -type f/ |grep -v Default.png$ |xargs -ILIST cp LIST destdir/
nr
quelle
1
Der erste Befehl ist nicht das, wonach das OP gefragt hat. Wenn Default.pngin den beiden Verzeichnissen vorhanden, wird das Ein-Verzeichnis destdirdurch das Ein- srcdirVerzeichnis ersetzt und das kopierte Verzeichnis gelöscht Default.png. Stattdessen möchte das OP das beibehalten, Default.pngwas bereits vorhanden ist destdir.
SnowFrog
2
Wie wäre es mit default.png, das bereits in destdir vorhanden ist? Ihre Lösung wird nicht funktionieren.
Iman Mohamadi
2

Dies funktioniert hervorragend, um alles außer Knotenmodulen zu kopieren :) Viel Spaß und dank der obigen Antworten habe ich es gerade hinzugefügt. Rsync ist meiner Meinung nach besser als CP, da Sie den Fortschrittsbalken sehen können, ohne danach zu fragen.

   rsync -av fromDirectory/ ToDirectory/ --exclude=node_modules
Josh
quelle
0
cp `ls | grep -v Default.png` destdir
Will Hartung
quelle
5
Dies führt eher zu Fehlern als zu dem, was Sie beabsichtigen.
Bis auf weiteres angehalten.
-1
# chattr +i /files_to_exclude
# cp source destination
# chattr -i /files_to_exclude
Ivan Grynenko
quelle
-2

Verwenden Sie den Erweiterungsparameter der Shell mit Regex

cp /<path>/[^not_to_copy_file]* .

Bis auf die Datei not_to_copy_file wird alles kopiert

- wenn damit etwas nicht stimmt. bitte angeben!

Alex
quelle
1
Willkommen bei SO. Leider ist Ihre Antwort nicht korrekt. Der Klammerausdruck ( [...]) enthält eine Reihe von übereinstimmenden Zeichen, während eine führende Zeichenfolge ^eine Übereinstimmung des Komplements der aufgelisteten Zeichen bewirkt. Im folgenden Beispiel wird keine der Dateien aufgelistet: touch not_to_copy_file to_copy_file ; ls [^not_to_copy_file]*Alle Dateinamen, die mit einem der folgenden Zeichen beginnen, werden ausgeschlossen : _cefilnopty.
RTX13