Dateien mit find + xargs verschieben: Ziel ist kein Verzeichnis?

9

Wenn ich den folgenden Befehl ausführe:

> mkdir some_dir
> find /foo/bar/ -name '*.csv' -print0 | xargs -0 mv {} some_dir

Ich bekomme Hunderte von Zeilen, die sagen:

mv: target `/foo/bar/XX.csv` is not a directory

Warum? Ich dachte, xargs würde ausführen:

mv /foo/barXX.csv some_dir

für jede Datei, die findfindet. Was ist los? Das ist übrigens bei zsh

Aktualisieren:

Update1:

Ich habe es versucht:

find /foo/bar/ -name '*.csv' -print0 | xargs -0 mv {} -t some_dir

aber dann habe ich ein paar Zeilen wie:

mv: cannot stat `{}': No such file or directory

obwohl ich denke, dass der Befehl meine Dateien korrekt verschiebt.

Update2:

Ich scheine die -tOption nicht zu brauchen, wenn ich sie mvalleine benutze . Zum Beispiel

> touch file1.txt
> touch file2.txt
> mkdir my_dir
> mv  file1.txt  file2.txt  my_dir

funktioniert gut. Warum brauche ich -tbei der Verwendung xargs?

Amelio Vazquez-Reina
quelle

Antworten:

14

Angenommen , Sie GNU haben ( find, xargs, & mv), ändern Sie Ihren Befehl dazu:

$ find /foot/bar/ -name '*.csv' -print0 | xargs -0 mv -t some_dir

Auszug aus der mvManpage

   -t, --target-directory=DIRECTORY
          move all SOURCE arguments into DIRECTORY

Mit dem obigen xargs ...Befehl wird der Befehl so erstellt, dass die Aufrufe zum Verschieben folgendermaßen aussehen:

 $ mv 1.csv 2.csv 3.csv ... -t some_dir

Ich brauche keine Xargs

Sie können diesen Ansatz überspringen, indem Sie nur finddie gesamte Arbeit selbst erledigen:

$ find /foot/bar/ -name '*.csv' -exec mv -t some_dir {} +

Warum brauchst du das mv -t ...?

Dies hat mit der Art und Weise zu tun, xargsin der die Dateigruppe erstellt wird, die an den Befehl übergeben wird, der jedes Mal ausgeführt wird (dh mv ...).

Wenn Sie den mvBefehl manuell selbst ausführen , steuern Sie, wie viele Dateinamen an ihn übergeben werden. Sie müssen sich also keine Sorgen machen, dass Sie den Befehl benötigen, -t my_dirda Sie das Zielverzeichnis immer als letztes festlegen.

Verweise

slm
quelle
Vielen Dank! Das ist sehr hilfreich. Ich bin allerdings etwas verwirrt (siehe meine Updates)
Amelio Vazquez-Reina
1
Der konstruierte Befehl ist mv -t some_dir 1.csv 2.csv 3.csv ...so, dass die Dateiargumente zuletzt sind. Das ist der Fehler in der Frage, zu verwenden , um {}Sie zu übergeben -I {}zu xargs.
Frostschutz
Vielen Dank. Das erklärt alles. Was ist mit der zweiten Frage, die ich in Update 2 hatte? Wissen Sie, warum ich nicht -tmit mehreren Dateien und einem Verzeichnis mit einem regulären brauche mv?
Amelio Vazquez-Reina
1
@ user815423426 - Ich werde es später aktualisieren, wenn ich heute Abend eine Chance bekomme. Ich weiß warum.
slm
@ user815423426 - Ich habe die Frage aktualisiert. Lassen Sie mich wissen, ob dies sinnvoll ist mv -t.
slm
1

Sie können auch den Befehl ls anstelle des Befehls find verwenden:

ls /foot/bar/*.csv | xargs  mv -t some_dir
Luis Ángel Rodríguez
quelle