it-swarm.com.de

Verwenden Sie xargs, um ein Verzeichnis aus den Suchergebnissen in ein anderes Verzeichnis zu verschieben

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?.

30
zjhui

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.

39

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.

38
user974202
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.

3
Evans Y.

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.

2
glenn jackman

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.

0
jlliagre