状況は、mpg321
ファイルリストをパラメータとして受け入れるMP3プレーヤーがあるということです。私は「音楽」というディレクトリに私の音楽を保存しましたが、そこにいくつかのディレクトリがあります。みんなで遊びたいので、プログラムを実行してみてください。
mpg321 $(find /music -iname "*\.mp3")
。問題は、いくつかのファイル名にスペースがあり、プログラムがこれらの名前をより小さな部分に分割し、ファイルの欠落について文句を言うことです。結果をfind
引用符で囲みます。
mpg321 "$(find /music -iname "*\.mp3")"
すべてが明らかに見つからない1つの大きな「ファイル名」に変わるので役に立ちません。
どうすればいいですか?それが重要であれば、私はそれを使用していますが、bash
すぐに切り替えます。zsh
答え1
-print0
次のようにfind'sまたはoptionを組み合わせて試してください。-printf
xargs
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に渡すことによって問題なく実行されます。