まず、些細なしかし不適当答え遮断する:私はどちらも使用することができますfind
+のxargs
トリックも(のようなその変種find
とを-exec
私は呼び出しごとにいくつかのような表現を使用する必要があるため)。最後にこれに戻ります。
より良い例として、次のことを考えてみましょう。
$ find -L some/dir -name \*.abc | sort
some/dir/1.abc
some/dir/2.abc
some/dir/a space.abc
それらを引数としてどのように渡すのprogram
ですか?
それをするだけではうまくいきません
$ ./program $(find -L some/dir -name \*.abc | sort)
program
次の引数を取得するため失敗します:
[0]: ./program
[1]: some/dir/1.abc
[2]: some/dir/2.abc
[3]: some/dir/a
[4]: space.abc
ご覧のとおり、スペースのあるパスは分割さprogram
れており、2つの異なる引数と見なされます。
機能するまで引用する
私のような初心者ユーザーは、そのような問題に直面したときに、最終的に機能するまでランダムに引用符を追加する傾向があります-ここではそれだけでは役に立たないようです…
"$(…)"
$ ./program "$(find -L some/dir -name \*.abc | sort)"
[0]: ./program
[1]: some/dir/1.abc
some/dir/2.abc
some/dir/a space.abc
引用符は単語分割を防ぐため、すべてのファイルは単一の引数として渡されます。
個々のパスを引用する
有望なアプローチ:
$ ./program $(find -L some/dir -name \*.abc -printf '"%p"\n' | sort)
[1]: "some/dir/1.abc"
[2]: "some/dir/2.abc"
[3]: "some/dir/a
[4]: space.abc"
引用符は確かにあります。しかし、それらはもはや解釈されません。それらは文字列の一部にすぎません。だから彼らは単語分割を妨げなかっただけでなく、彼らは議論に入った!
IFSを変更する
次に、で遊んでみましたIFS
。私はとにかくそしてとにかく-彼らが「ワイヤードパス」自体に問題がないように- と一緒にしたいfind
と思います。それでは、文字の単語分割を強制して、それをすべて持ってみませんか?-print0
sort
-z
null
$ ./program $(IFS=$'\0' find -L some/dir -name \*.abc -print0 | sort -z)
[0]: ./program
[1]: some/dir/1.abcsome/dir/2.abcsome/dir/a
[2]: space.abc
したがって、それでもスペースで分割され、では分割されませんnull
。
(上記のように)と前のIFS
両方に割り当てを配置しようとしました。また、私は次のように他の構文を試してみました、、両方で引用され及び場合とない場合と同様。それらのどれも違いを生むように見えなかった…$(…)
./program
\0
\x0
\x00
'
"
$
そして、ここで私はアイデアがありません。私はいくつかのことを試してみましたが、すべてがリストされているのと同じ問題に陥ったようです。
他に何ができますか?それはまったく可能ですか?
もちろん、program
パターンを受け入れて検索自体を行うことができました。しかし、それを特定の構文に修正する間は、多くの二重の作業です。(grep
たとえば、ファイルを提供するのはどうですか?)
またprogram
、パスのリストを含むファイルを受け入れるようにすることもできます。次に、find
式を一時ファイルに簡単にダンプして、そのファイルへのパスのみを指定できます。これは直接パスに沿ってサポートされるため、ユーザーが単純なパスだけを持っている場合は、中間ファイルなしで提供できます。しかし、これは良くないように見えます-必要な追加の実装は言うまでもなく、追加のファイルを作成してそれらを処理する必要があります。(ただし、引数としてのファイルの数がコマンドラインの長さに問題を引き起こし始める場合には、これが救いになるかもしれません…)
最後に、find
+ xargs
(および同様の)トリックは私の場合は機能しないことをもう一度思い出させてください。説明を簡単にするために、私は1つの引数のみを示しています。しかし、私の本当のケースは次のようになります。
$ ABC_FILES=$(find -L some/dir -name \*.abc | sort)
$ XYZ_FILES=$(find -L other/dir -name \*.xyz | sort)
$ ./program --abc-files $ABC_FILES --xyz-files $XYZ_FILES
そのためxargs
、1つの検索からを実行しても、他の検索に対処する方法が残ります…
mapfile
(またはその同義語readarray
)。しかし、それはうまくいきます!