Ich habe den folgenden Befehl:
find . -type d -mtime 0 -exec mv {} /path/to/target-dir \;
Dadurch wird das Verzeichnis in ein anderes Verzeichnis verschoben. Wie kann ich xargs
anstelle von exec
verwenden, um dasselbe zu tun?.
Wenn Sie GNU mv
(und find
und xargs
) haben, können Sie die Option -t
für mv
(und -print0
für find
und -0
für xargs
) verwenden:
find . -type d -mtime -0 -print0 | xargs -0 mv -t /path/to/target-dir
Beachten Sie, dass moderne Versionen von find
(kompatibel mit POSIX 2008) +
anstelle von ;
unterstützen und sich in etwa wie xargs
verhalten, ohne xargs
zu verwenden:
find . -type d -mtime -0 -exec mv -t /path/to/target-dir {} +
Dies macht find
bequeme Nummern von Dateinamen (Verzeichnisnamen) in einem einzigen Aufruf des Programms. Sie haben nicht die Kontrolle über die Anzahl der Argumente, die an mv
übergeben werden, die xargs
bereitstellt, aber Sie benötigen das sowieso selten. Dies hängt weiterhin von der -t
-Option für GNU mv
ab.
Mit BSD xargs (für OS X und FreeBSD) können Sie -J
verwenden, der dafür erstellt wurde:
find . -name some_pattern -print0 | xargs -0 -J % mv % target_location
Das würde alles, was some_pattern
in .
entspricht, zu target_location
verschieben.
Verwenden Sie bei GNU xargs (für Linux und Cygwin) stattdessen -I
:
find . -name some_pattern -print0 | xargs -0 -I % mv % target_location
Die veraltete -i
-Option von GNU xargs impliziert -I{}
und kann wie folgt verwendet werden:
find . -name some_pattern -print0 | xargs -0 -i mv {} target_location
Beachten Sie, dass BSD xargs auch eine -I
-Option hat, aber das tut etwas anderes.
find ./ -maxdepth 1 -name "some-dir" -type d -print0 | xargs -0r mv -t x/
find : mit der Option -print0
endet die Ausgabe mit '\ 0';
xargs : Mit der Option -0
werden die Argumente nach '\ 0' aufgeteilt. Whitespace, -r
bedeutet, dass kein Run-if-empty ausgeführt wird. Wenn find
keine Ausgabe erhalten hat, werden keine Fehler angezeigt . (Der -r
ist eine Erweiterung von GNU.)
Ich verwende dies normalerweise in Skripts, wenn ich nicht sicher bin, ob die Zieldateien existieren oder nicht.
find
ist dafür kein wirklich gutes Werkzeug. Ich stelle mir vor, Sie möchten alle Unterverzeichnisse in ein anderes Verzeichnis verschieben. find
gibt Dinge wie aus
./a
./a/b
./a/b/c
./a/b/c/d
Nachdem ./a
zuerst verschoben wurde, werden nur Fehler angezeigt, die besagen, dass keine solchen Dateien oder Verzeichnisse vorhanden sind.
Sie sollten einfach mv */ /another/place
verwenden - der abschließende Schrägstrich auf dem Platzhalter beschränkt die Erweiterung auf nur Verzeichnisse.
Wenn Sie GNU mv nicht verwenden, können Sie diesen Befehl verwenden:
find . -depth -type d -mtime 0 -exec bash -c 'declare -a array;j=1;for i; do array[$j]="$i"; j=$((j+1));done; mv "${array[*]}" /path/to/target-dir' arg0 {} +
ansonsten ist hier eine einfachere Lösung, die keine xargs erfordert:
find . -depth -type d -mtime 0 -exec mv -t /path/to/target-dir {} +
Beachten Sie, dass ich -depth hinzugefügt habe. Andernfalls werden Fehler auftreten, wenn ein Verzeichnis und eines seiner Unterverzeichnisse verarbeitet werden sollen.