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?

Antworten:


36

Versuchen:

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

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

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/{}

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/ \;

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/{}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.