Ich versuche, einen Befehl auszuführen, der dem folgenden in einem Bash-Skript ähnlich ist. Es sollte alle Unterordner von durchsuchen $sourcedir
und alle Dateien eines bestimmten Typs in das Stammverzeichnis von kopieren $targetdir
.
#!/bin/bash
# These are set as arguments to the script, not hard-coded
sourcedir="/path/to/sourcedir"
targetdir="/path/to/targetdir"
find "$sourcedir" -type f -name "*.type" -exec sh -c 'cp "$1" "$2/`basename "$1"`"' "{}" "$targetdir" \;
Das scheint ziemlich nahe zu sein, außer , dass {}
nicht in so geführt wird , $2
um-exec sh -c ...
Ich möchte dies so nah wie möglich am "richtigen Weg" tun, mit Toleranz für Sonderzeichen in Dateinamen (insbesondere einfache Anführungszeichen).
Bearbeiten: Ich sehe Leute, die die Verwendung xargs
oder Verkettung von Argumenten vorschlagen . Ich hatte den Eindruck, dass dies nur für eine begrenzte Anzahl von Argumenten in Ordnung ist. Wenn ich zum Beispiel Tausende von JPG-Dateien habe, die ich aus einer Reihe von Galerieverzeichnissen in ein riesiges Diashow-Verzeichnis zu kopieren versuche, funktionieren die Argumente für die Verkettung von Lösungen dann immer noch?
Edit 2: Mein Problem war, dass mir eine _
vor meiner ersten Option fehlte, um in den -exec
Befehl zu wechseln . Für alle, die neugierig sind, wie der Befehl find funktioniert, fügen Sie den Befehl _
und alles wird gut:
find "$sourcedir" -type f -name "*.type" -exec sh -c 'cp "$1" "$2"' _ "{}" "$targetdir" \;
Ich habe die Antwort unten zwar akzeptiert, weil sie dieselbe Aufgabe erfüllt, aber effizienter und eleganter ist.
quelle
xargs
wurde jemals entwickelt, um große Mengen von Argumenten bei regulären Befehlen mit Einschränkungen automatisch zu verarbeiten. Zu beachten ist auch, dass die meisten der maximalen Argumentgrenzen für die Standard-GNU-Utils erheblich verbessert wurden. Sie werden auch einen Leistungsvorteil sehen, indem Sie alle diese Prozessgabeln vermeiden, die für Tausende von Dateien relevant sind.Antworten:
Sie möchten Dateien eines bestimmten Typs in ein bestimmtes Verzeichnis kopieren? Dies ist am besten mit
xargs
, und Sie brauchen das nicht einmalsh
. Dies ist ein geeigneterer Weg, um es zu tun, sollte auch effizienter laufen.Wenn Sie spezielle Dateinamen benötigen, verwenden Sie diese
NULL
als Trennzeichenquelle
-print0
zufind
und-0
zuxargs
NULL
ist es nicht notwendig, wenn Sie verwenden'{}'
, es ist wichtig, wenn Sie es nicht tun. Der eigentliche Vorteil zwischen den beiden ist,POSIX
abgesehen von der Einhaltung, die Leistung.Sie müssen
{}
der Shell ein Argument übergeben und dann die einzelnen Argumente durchlaufen.Hinweis : So funktioniert es, dass das erste Argument für eine Shell der Name der Shell ist. Sie können dies ausnutzen, indem Sie den Namen als übergeben
$targetdir
und dann den speziellen Parameter$0
im Shell-Skript verwenden, um auf dieses Zielverzeichnis zuzugreifen.quelle
"$targetdir"
wird nicht in einfache Anführungszeichen gesetzt.Wenn Sie nicht an die Kirche von Xargs glauben:
Erläuterung:
kopiert b, c und d in das Zielverzeichnis a.
Ruft den Befehl für eine große Anzahl von Dateien gleichzeitig und nicht nacheinander auf (was Standard ist, wenn Sie
";"
anstelle von verwenden+
). Deshalb muss das targetdir nach vorne gezogen und explizit als target markiert werden.Dies funktioniert für gnu-find und möglicherweise nicht für andere find-Implementierungen. Natürlich hängt es auch von der -t-Flagge ab.
TechZilla hat natürlich insofern recht, als
sh
es nicht nötig ist, um cp aufzurufen.Wenn Sie nicht verwenden
xargs
, was in Kombination mit die meiste Zeit unnötig istfind
, können Sie das-print0
und--0
Flag nicht lernen .quelle
xargs
. Das größte Beispiel: Was ist, wenn Sie keine Dateien finden? Ich benutze xargs anstelle von Generalfor
Loops, derfind
Umfang ist viel kleiner.find
Unterstützt außerdem nur, dass+
GNUfind
in POSIX nicht definiert ist. Also, während Sie sich frei fühlen sollten, esfind
alleine zu bevorzugen , tut es nicht alles, was xargs tut. Wenn Sie GNU betrachtenxargs
, bekommen Sie auch,-P
was Multi-Core macht. Es lohnt sich trotzdem zu lernenxargs
.quelle