Linux: Kopieren Sie alle Dateien, die mit dem Muster übereinstimmen, von dir und den Unterverzeichnissen in ein einziges Verzeichnis

31

Wenn ich alle *.soDateien von srcnach kopieren dstmöchte, mache ich Folgendes:

cp src/*.so dst

Ich möchte jedoch alle *.soDateien von src und seinen Unterverzeichnissen in kopierendst . Irgendwelche Hinweise?

Albus Dumbledore
quelle

Antworten:

36

Versuchen:

find src/ -type f | grep -i so$ | xargs -i cp {} dst
Mike Insch
quelle
17
findKann Pattern Matching durchführen und Befehle ausführen. Die Ausgabe muss nicht weitergeleitet werden:find src/ -type f -name '*.so' -exec cp '{}' dst/ ';'
Januar,
1
Ja, es kann, jedoch ist es oft einfacher, eine Pipeline zu lesen, auch die Pattern-Matching-Fähigkeiten grepüberwiegen bei weitem die einfachen Shell-Patterns, die im -nameParameter verwendet werden find. xargsist auch weitaus leistungsfähiger als der -execParameter zu find.
Mike Insch
2
Die Lösung von @jaquer ist viel besser, da das Dienstprogramm xargs unter MacOSX nicht die Option -i hat. Aber seine Lösung wirkt wie ein Zauber.
Bialix
Ich hatte Probleme mit einer Fehlermeldung beim Argument -i für xargs, bis ich den Kommentar von @bialix zur Jaquer-Lösung las, die auf meinem Mac perfekt funktionierte. Vielen Dank
Svannoy
Werden dadurch nach Bedarf Unterverzeichnisse erstellt?
Lennart Rolland
15

Wenn Sie Bash verwenden, können Sie die globstar Shell-Option aktivieren , um Dateien und Verzeichnisse rekursiv abzugleichen:

shopt -s globstar
cp src/**/*.so dst

Wenn Sie Dateien suchen müssen, deren Namen mit .und / oder Dateien in und unter Verzeichnissen beginnen ., deren Namen mit beginnen , setzen Sie die dotglobOption ebenfalls (z shopt -s dotglob. B. mit ). Sie können beide in einem Befehl festlegen:

shopt -s globstar dotglob
jáquer
quelle
Kopiert keine Dateien in Unterverzeichnissen, die mit einem beginnen. in ihrem Namen
rboy
8

Ich habe den von Mike vorgeschlagenen Befehl ausprobiert:

find src/ -type f | grep -i so$ | xargs -i cp {} dst

Es endete jedoch damit, dass alle Dateien in einem Verzeichnis abgelegt wurden dstund ihre relativen Pfade verloren gingen.

Um die relativen Pfade beizubehalten, muss der Befehl folgendermaßen geändert werden:

find src/ -type f | grep -i so$ | xargs -i cp {} dst/{}
Ilya Druker
quelle
7
+1. Dies setzt jedoch voraus, dass die Verzeichnisse, die den relativen Quellpfaden entsprechen, unter existieren dst. Falls dies nicht der Fall ist, verwenden Sie cp --parents. Stellen Sie außerdem sicher, dass Sie die Dateinamen angeben. Also: ... | xargs -i cp --parents "{}" dst(Beachten Sie, dass das letzte Argument cp"nur" das Zielverzeichnis ist). Der Befehl kann mit dem -tFlag: noch kürzer (und wahrscheinlich auch schneller) gemacht werden ... | xargs cp --parents -t dst.
Stephan202
1
@ Stephan202 musste ich benutzen... | xargs cp {} --parents -t dst.
warvariuc
für die auf einem Mac --parentsist nicht verfügbar. Ich habe dittoan seiner Stelle verwendet: stackoverflow.com/questions/11246070/cp-parents-option-on-mac
Bryan Young
3

Ein anderer Weg dies zu tun ist wie folgt:

find src/ -type f -name "*.so" -exec cp {} dst/ \;
Kyriakos
quelle
Und dies sollte Anzahl reduzieren cpProzesse: ... -exec cp -t dst/ {} +.
Kamil Maciorowski
Hey Kamil! Danke für den Kommentar! Können Sie mir bitte erklären, wie Ihre Lösung die Dinge schneller macht! Immer bereit, mehr zu lernen :)
Kyriakos
Wenn Sie am Ende -execmit ;, {}wird durch einen Pfad zu einem Zeitpunkt ersetzt. Sie erhalten cpfür jede Datei eine eigene . Mit +Syntax findErsetzt {}mit mehreren Ergebnissen (bis zu einer systemdefinierte Grenze der Befehlszeilenlänge; Einschränkung: {}muß das letzte , was vor +, damit cp -t). Das Erstellen und Beenden eines Prozesses ist relativ kostspielig. Aus diesem Grund ist es gut zu verwenden, +wenn Sie viele Ergebnisse erwarten. In diesem Fall kann das Kopieren vieler Dateien ohnehin viel Zeit in Anspruch nehmen, sodass der Unterschied unbemerkt bleibt. Trotzdem ist es eine gute Übung.
Kamil Maciorowski
1

Das grep kann mit find's -name ersetzt werden :

find src/ -type f -name "*.so" | xargs -i cp {} dst/{}
Th. Thielemann
quelle