「検索」結果をファイルリストにどのように渡すことができますか?

「検索」結果をファイルリストにどのように渡すことができますか?

状況は、mpg321ファイルリストをパラメータとして受け入れるMP3プレーヤーがあるということです。私は「音楽」というディレクトリに私の音楽を保存しましたが、そこにいくつかのディレクトリがあります。みんなで遊びたいので、プログラムを実行してみてください。

mpg321 $(find /music -iname "*\.mp3")

。問題は、いくつかのファイル名にスペースがあり、プログラムがこれらの名前をより小さな部分に分割し、ファイルの欠落について文句を言うことです。結果をfind引用符で囲みます。

mpg321 "$(find /music -iname "*\.mp3")"

すべてが明らかに見つからない1つの大きな「ファイル名」に変わるので役に立ちません。

どうすればいいですか?それが重要であれば、私はそれを使用していますが、bashすぐに切り替えます。zsh

答え1

-print0次のようにfind'sまたはoptionを組み合わせて試してください。-printfxargs

find /music -iname "*\.mp3" -print0 | xargs -0 mpg321

これがどのように機能するかは、次のように説明されています。検索マニュアルページ:

-0を印刷してください。

Trueの場合、標準出力にファイル名全体を印刷し、その後にヌル文字(-printで使用される改行文字の代わりに)を印刷します。これにより、find 出力を処理するプログラムが改行またはその他の種類のスペースを含むファイル名を正しく解釈できます。このオプションは xargs の -0 オプションに対応します。

答え2

find /music -iname "*\.mp3" -exec mpg123 {} +

GNU findを使用すると、次のものも使用できます。-print0そしてxargs -0しかし、他のツールを学ぶことはほとんど意味がありません。この-exec ... {} +構文はLinuxで遅く実装されているためほとんど言及されていませんが、-print0今は使用しない理由はありません。

zshまたはbash 4を使用すると、はるかに簡単です。

mpg123 **/*.[Mm][Pp]3

zshでのみ(一部の)パターンを大文字と小文字を区別しないようにすることができます。

mpg123 (#i)**/*.mp3

答え3

私の考えではスティーブンのソリューションベストですが、別の方法は xargs-Iフラグを使用することです。これにより、文字列を指定してから、その文字列をコマンドの引数に置き換えることができます(コマンドの末尾に引数を追加する代わりに)。これを使用してパラメータを参照できます。

find /music -iname "*\.mp3" | xargs -0 -Ifoo mpg321 "foo"

答え4

別の方法は、ファイル名に表示される特殊文字をエスケープすることです。たとえば、

find /music -iname "*\.mp3" | sed 's!\([] \*\$\/&[]\)!\\\1!g' | xargs mpg321

これはデフォルトで正しくエスケープされたファイル名をxargsに渡すことによって問題なく実行されます。

関連情報