Frage Warum funktioniert meine Pipeline nicht?


Ich versuche ein Bash-Skript zu erstellen, das alle MP3s in meinem Downloads-Ordner findet und sie in einen Musikordner verschiebt. Warum wird diese Linie nicht funktionieren?

find ./ -type f -name \*.mp3 | mv *.mp3 /home/mitch/Desktop/Music/$ARTIST

Ich habe versucht, eine Pipeline zu verwenden, um die Informationen aus dem ersten Befehl in den zweiten übersetzen zu lassen, aber ich habe noch nie zuvor eine Pipeline verwendet und weiß nicht, ob ich falsch liege oder ob ich eine falsche Vorstellung davon habe, wofür sie verwendet werden zum.


2
2018-03-01 06:38


Ursprung




Antworten:


Das mv Befehl verwenden Sie nicht seine stdin, also müssen Sie die stdin in einen Parameter übersetzen, und dafür kann verwendet werden xargs:

find ./ -type f -name '*.mp3' | xargs mv -t /home/mitch/Desktop/Music/$ARTIST

Sie können auch direkt die -exec Aktion von find:

find ./ -type f -name '*.mp3' -exec mv {} /home/mitch/Desktop/Music/$ARTIST ';'

Bearbeiten

Wie von @geirha gezeigt, funktioniert der erste Befehl nicht, wenn Sie Dateinamen mit Leerzeichen haben. In einem solchen Fall sollte es wie folgt sein

find ./ -type f -name '*.mp3' -print0 | xargs -0 mv -t /home/mitch/Desktop/Music/$ARTIST

5
2018-03-01 06:45



Hey vielen Dank. Der erste funktionierte aus irgendeinem Grund nicht, der zweite jedoch. Ich beginne gerade mit dem Zeug, also weiß ich nicht, was die Teile, die du hinzugefügt hast, bedeuten, aber hoffentlich kann ich es herausfinden. - LurkDog
@LurkDog, der erste mit Xargs, wird fehlschlagen, wenn einer der Dateinamen Whitespace- oder Anführungszeichen enthält. Das ist wahrscheinlich der Grund, warum es für Sie fehlgeschlagen ist. Der zweite, der stattdessen finds -exec verwendet, ist in dieser Hinsicht 100% sicher. Egal, welche Zeichen die Dateinamen enthalten, sie werden an int int weitergegeben. - geirha


Der Vorteil von xargs ist die Erweiterung der Befehlszeile. Wenn Sie einen Befehl haben, der eine sehr große Menge an Text (oder viele Dateien in einem Befehl) zurückgibt, würden Sie Xargs benötigen.

Wenn Sie mehrere tausend Dateien in einem Verzeichnis hatten und ein Skript auf dieser Liste ausführen wollten, könnten Sie versuchen "./myprogram *", aber wenn Ihr Programm irgendwelche Beschränkungen bezüglich der Größe eines Parameters hat, können Sie den Puffer durch das Erweitern von * blasen. Auch die Befehlszeile selbst hat Grenzen, so dass der Befehl fehlschlägt, weil der Befehlszeilenpuffer überläuft. Die Verwendung von xargs wird vermeide das Problem.

Schließlich wird der Parameter -print0 on find Nulltrennzeichen für Leerzeichen in den zurückgegebenen Dateinamen eingeben, und die Option -0 in xargs interpretiert diese Nullen. Lesen man xargs.


0
2017-09-01 23:53