Wie kopiere ich einige, aber nicht alle Dateien?

54

Sie können also die *als Platzhalter für alle Dateien verwenden, wenn Sie sie cpim Kontext eines Verzeichnisses verwenden. Gibt es eine Möglichkeit, alle Dateien außer der xDatei zu kopieren ?

Chad Harrison
quelle

Antworten:

42

In können bashSie verwenden extglob:

 $ shopt -s extglob  # to enable extglob
 $ cp !(b*) new_dir/

wo !(b*)alle b*Dateien ausschließen.

Sie können später deaktivieren extglobmit

 $ shopt -u extglob
eilen
quelle
Wissen Sie, ob es für die tcsh-Shell etwas Äquivalentes gibt?
Levon
Leider nicht. Scheint, findist der einzige Weg in tcsh:find . -maxdepth 1 ! -name "exclude*" -exec cp -t destination {} \+
Ansturm
50

Rsync handhabt dies gut.

Beispiel alle kopieren: rsync -aP /folder1/* /folder/2

Beispiel kopieren alle mit Ausschluss: rsync -aP --exclude=x /folder1/* /folder2/

Der -aPSchalter:

a: Ähnlich wie cp -a, rekursiv usw. P: Zeigt den Fortschritt an, eine nette Funktion von rsync.

Tim
quelle
5
In dieser Antwort finden Sie eine kurze Anleitung zu allgemeinen rsync-Ausschlusslisten.
Gilles 'SO- hör auf böse zu sein'
1
Verwenden Sie unter Darwin / MacOS -rPanstelle von, -aPwenn Sie wiederkehren möchten. -aist für die Archivierung. Ich bin mir nicht sicher, ob sich dies geändert hat oder ob es nur unter MacOS anders ist.
Jpoveda
rsynchat die Option, es rekursiv zu machen. Beispiel: rsync --recursive -P --exclude=x /folder1/* /folder2/. (Getestet nur auf Ubuntu)
n1k31t4
12

Dies ist keine Funktion von cp, es ist eine Funktion Ihrer Shell (es erweitert sich *, um alle Nicht-Punkt-Dateien zu bedeuten), daher hängt die Antwort davon ab, welche Shell Sie verwenden. zshUnterstützt zum Beispiel diese Syntax:

$ cp ^x /path/to/destination

Wo ^xbedeutet "alle Dateien außer x"

Sie können auch Selektions- und Deselektionsmuster kombinieren, um z. B. alle WAV-Dateien mit Ausnahme derjenigen, die xyz enthalten, zu kopieren, können Sie Folgendes verwenden:

cp *.wav~*xyz*
Michael Mrozek
quelle
Irgendwelche Kommentare zu bash?
Chad Harrison
@hydroparadise Ich weiß nicht viel über bash, aber diese Antwort scheint es zu decken
Michael Mrozek
Was ist mit tcsh? Weiß jemand?
Levon
4

Könnte auch in einer einfachen alten (portablen / kompatiblen) Borowski-Shell auf vielfältige Weise mit Standardwerkzeugen auf weniger elegante Weise ausgeführt werden als mit erweiterten Shell-Globbing- oder -Befehlen mit integrierten Ausschlussoptionen.

Wenn es nicht zu viele Dateien gibt (und keine Namen mit Leerzeichen und / oder Zeilenumbrüchen), kann dies eine Möglichkeit sein:

cp `ls | egrep -v '^excludename$'` destdir/.

Sicher, bashund GNU-Tools sind großartig und leistungsstark, aber sie sind immer noch nicht immer verfügbar. Wenn Sie beabsichtigen, es in ein portables Skript zu schreiben, würde ich dies findwie im Kommentar von Rush empfehlen .

MattBianco
quelle
2
Ich stelle fest, dass der letzte Teil Ihrer Antwort nur vom eigentlichen Thema ablenkt. Außerdem ist "Unix" nicht mehr der Goldstandard (wenn es jemals war). Es ist einfach nicht so wichtig, ob etwas "Unix" ist oder nicht, obwohl der Titel dieser Site "Unix and Linux" ist.
Alexander
2
OKAY. Ich habe stattdessen den Kommentar hierher verschoben: Unix ist nicht GNU. Ich stimme zu, dass das "Unix" der Dinge nicht sehr interessant ist, aber ich glaube immer noch an Portabilität und ein bisschen Wissen über Ihre Geschichte.
MattBianco
Da stimme ich dir voll zu.
Alexander
2

Wenn Sie alles in einem Ordner (einschließlich Unterordner) in ein bestimmtes Unterverzeichnis kopieren möchten:

cp -R $(ls | grep -v '^subdir$') subdir/

Funktioniert mit sh, bash, zsh (zumindest).

user2707671
quelle
1
Überzeugen Sie mich, das ist nicht die gleiche Absicht wiecp -R * subdir/
Roaima
1
Wenn Sie den Befehl "cp -R * subdir /" verwenden, hat bash / zsh versucht, "subdir" rekursiv zu kopieren. Sie erhalten den Fehler "Name zu lang (nicht kopiert)".
user2707671
Guter Punkt. Ihr Vorschlag versucht, die Warnung von cp(nicht von bash/ sh), " cp: cannot copy a directory, ‘subdir’, into itself, ‘subdir/subdir’" zu vermeiden . Die Kopie wird jedoch korrekt abgeschlossen. Leider bricht Ihre Variante mit einem Dateinamen, der ein Leerzeichen oder eine Shell-sensitive Interpunktion enthält. Siehe unix.stackexchange.com/q/128985/135943
roaima
-1

extglob ist der beste Weg, soweit ich denke.

Ein anderer Weg ist die Verwendung cp $(ls --ignore=x) subdir/

Edwin Lee
quelle
Dies führt bei jeder Form von Sonderzeichen in den Dateinamen zum Bruch. (Leerzeichen, Zeilenumbrüche $usw.) Analysieren Sie niemals die Ausgabe von ls. unix.stackexchange.com/q/128985/135943
Wildcard