パイプラインが機能しないのはなぜですか?

パイプラインが機能しないのはなぜですか?

ダウンロード フォルダー内のすべての mp3 を検索し、それらを音楽フォルダーに移動する bash スクリプトを作成しようとしています。この行が機能しないのはなぜですか?

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

パイプラインを使用して最初のコマンドの情報を 2 番目のコマンドに変換しようとしましたが、パイプラインを使用したことがなく、やり方が間違っているのか、パイプラインの用途について間違った考えを持っているのかわかりません。

答え1

このmvコマンドは標準入力を使用しないため、標準入力をパラメータに変換する必要があります。これには以下を使用できますxargs

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

また、-exec次のアクションを直接使用することもできますfind:

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

編集

@geirha が指摘したように、最初のコマンドはファイル名にスペースが含まれている場合には機能しません。そのような場合は次のようにします。

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

答え2

xargs の利点は、コマンド ラインの拡張です。非常に大量のテキストを返すコマンド (または 1 つのコマンドで多数のファイルを返すコマンド) がある場合は、xargs が必要になります。

ディレクトリ内に数千のファイルがあり、そのリストに対して何らかのスクリプトを実行したい場合は、" ./myprogram *" を試すことができますが、プログラムにパラメータのサイズ制限がある場合は、* を展開するとバッファがオーバーランする可能性があります。また、コマンド ライン自体にも制限があるため、コマンド ライン バッファがオーバーランしてコマンドが失敗する可能性があります。xargs を使用すると、この問題を回避できます。

最後に、find の -print0 は、返されるファイル名のスペースに null 区切り文字を配置し、xargs の -0 オプションはそれらの null を解釈します。 をお読みくださいman xargs

関連情報