Ich suche mit folgendem Befehl nach Dateien, deren Namen AAA
in ihrem Pfad enthalten:
find path_A -name "*AAA*"
Angesichts der Ausgabe des obigen Befehls möchte ich diese Dateien in einen anderen Pfad verschieben, sagen wir Pfad_B
. Kann ich den Befehl optimieren, indem ich die Dateien direkt nach dem Find-Befehl verschiebe, anstatt sie eine nach der anderen zu verschieben?
Mit GNU mv:
find path_A -name '*AAA*' -exec mv -t path_B {} +
Das wird find's -exec
Option benutzen, die das {}
mit jedem Suchergebnis ersetzt und den Befehl ausführt, den Sie ihm geben. Wie in man find
erklärt:
-exec command ;
Execute command; true if 0 status is returned. All following
arguments to find are taken to be arguments to the command until
an argument consisting of `;' is encountered.
In diesem Fall benutzen wir die +
Version von -exec
, damit wir so wenig mv
Operationen wie möglich ausführen:
-exec command {} +
This variant of the -exec action runs the specified command on
the selected files, but the command line is built by appending
each selected file name at the end; the total number of invoca‐
tions of the command will be much less than the number of
matched files. The command line is built in much the same way
that xargs builds its command lines. Only one instance of `{}'
is allowed within the command. The command is executed in the
starting directory.
Sie könnten auch so etwas wie unten machen.
find path_A -name "*AAA*" -print0 | xargs -0 -I {} mv {} path_B
Wo,
-0
Wenn Leerzeichen oder Zeichen (einschließlich Zeilenumbrüche) vorhanden sind, werden viele Befehle nicht funktionieren. Diese Option kümmert sich um Dateinamen mit
Leerzeichen.-I
Ersetze Vorkommen von replace-str in den Anfangsargumenten durch Namen, die von der Standardeingabe gelesen werden. Außerdem werden nicht in Anführungszeichen gesetzte Leerzeichen nicht
keine Eingabeelemente; stattdessen ist das Trennzeichen das Newline
Zeichen.Testen
Ich habe zwei Verzeichnisse erstellt, sourcedir
und destdir
. Nun habe ich eine Reihe von Dateien in sourcedir
erstellt, und zwar file1.bak
, file2.bak
und file3 with spaces.bak
.
Jetzt habe ich den Befehl wie folgt ausgeführt,
find . -name "*.bak" -print0 | xargs -0 -I {} mv {} /destdir/
Wenn ich nun innerhalb des destdir
ls
ausführe, kann ich sehen, dass die Dateien von sourcedir
nach destdir
verschoben wurden.
Referenzen
http://www.cyberciti.biz/faq/linux-unix-bsd-xargs-construct-argument-lists-utility/
Die -exec
ist der beste Weg, dies zu tun. Wenn dies aus irgendeinem Grund nicht möglich ist, können Sie die Ergebnisse auch in einer Schleife lesen:
find path_A -name "*AAA*" -print0 |
while IFS= read -r -d $'\0' file; do mv "$file" path_B; done
Das ist der sichere Weg, er kann mit Dateinamen umgehen, die Leerzeichen, Zeilenumbrüche oder andere seltsame Zeichen enthalten. Ein einfacherer Weg, der aber nur dann nicht funktioniert, wenn Ihre Dateinamen nur aus einfachen alphanumerischen Zeichen bestehen, ist
mv $(find path_A -name "*AAA*") path_B
Verwenden Sie aber die while-Schleife.