
Ich versuche, ein Bash-Skript zu erstellen, das alle MP3s in meinem Download-Ordner findet und in einen Musikordner verschiebt. Warum funktioniert diese Zeile nicht?
find ./ -type f -name \*.mp3 | mv *.mp3 /home/mitch/Desktop/Music/$ARTIST
Ich habe versucht, mithilfe einer Pipeline die Informationen des ersten Befehls in den zweiten zu übersetzen, aber ich habe noch nie zuvor eine Pipeline verwendet und weiß nicht, ob ich es falsch mache oder ob ich eine falsche Vorstellung davon habe, wofür sie verwendet werden.
Antwort1
Der mv
Befehl verwendet nicht die Standardeingabe, daher müssen Sie die Standardeingabe in einen Parameter übersetzen. Dafür kann Folgendes verwendet werden xargs
:
find ./ -type f -name '*.mp3' | xargs mv -t /home/mitch/Desktop/Music/$ARTIST
-exec
Sie können die folgende Aktion auch direkt verwenden find
:
find ./ -type f -name '*.mp3' -exec mv {} /home/mitch/Desktop/Music/$ARTIST ';'
Bearbeiten
Wie @geirha bemerkt hat, funktioniert der erste Befehl nicht, wenn Ihre Dateinamen Leerzeichen enthalten. In einem solchen Fall sollte er wie folgt lauten:
find ./ -type f -name '*.mp3' -print0 | xargs -0 mv -t /home/mitch/Desktop/Music/$ARTIST
Antwort2
Der Vorteil von xargs ist die Befehlszeilenerweiterung. Wenn Sie einen Befehl hätten, der eine sehr große Menge Text zurückgibt (oder viele Dateien in einem Befehl), würden Sie xargs benötigen.
Wenn Sie mehrere tausend Dateien in einem Verzeichnis haben und ein Skript auf dieser Liste ausführen möchten, können Sie " ./myprogram *
" versuchen. Wenn Ihr Programm jedoch Beschränkungen für die Größe eines Parameters hat, können Sie den Puffer durch die Erweiterung von * sprengen. Auch die Befehlszeile selbst hat Beschränkungen, sodass der Befehl fehlschlagen kann, weil der Befehlszeilenpuffer überläuft. Die Verwendung von xargs vermeidet das Problem.
Schließlich setzt die Option -print0 bei find Null-Trennzeichen für Leerzeichen in den zurückgegebenen Dateinamen, und die Option -0 bei xargs interpretiert diese Nullen. Lesen man xargs
.