GNU findのマニュアルページには、次の内容が記載されています。
-exec command ; [...] The string `{}' is replaced by the current file name being processed everywhere it occurs in the arguments to the command, not just in arguments where it is alone, as in some versions of find. Both of these constructions might need to be escaped (with a `\') or quoted to protect them from expansion by the shell.
これは(GNU findutils)4.4.2のmanの投稿ですfind
。
これでbashとdashでこれをテストしましたが、両方を{}
ブロックする必要はありません。簡単なテストは次のとおりです。
find /etc -name "hosts" -exec md5sum {} \;
キャリブレーターをカバーするために必要なカバーがありますか?見つかったファイルに空白(bashから呼び出される)が含まれているかどうかに依存しません。
find ~ -maxdepth 1 -type d -name "U*" -exec ls -d {} \;
/home/stefan/Ubuntu One
見つかったファイルがサブシェルに渡されると、状況は異なります。
find ~ -maxdepth 3 -type d -name "U*" -exec bash -c 'ls -d {}' \;
ls: cannot access /home/stefan/Ubuntu: No such file or directory
ls: cannot access One: No such file or directory
この問題は次の方法で解決できます。
find ~ -maxdepth 3 -type d -name "U*" -exec bash -c 'ls -d "$0"' {} \;
比較してみると:
find ~ -maxdepth 3 -type d -name "U*" -exec bash -c 'ls -d "{}"' \;
/home/stefan/Ubuntu One
しかし、マニュアルページではそのような内容を扱いません。そうですか?それでは、どのシェルが{}
これを別の方法で処理しますか?
ベストアンサー1
一般化する: 拡張可能なシェルがあれば、{}
今は本当に古いレガシーです。
BourneシェルとPOSIX互換シェルでは、中かっこ(および{
)}
は一般的な文字です(ワイルドカード文字、andなどの(
単語)
区切り記号、andとは異なります)。次の文字列はすべて文字通り印刷する必要があります。;
&
[
]
$ echo { } {} {foo,bar} {1..3}
{ } {} {foo,bar} {1..3}
1つの中括弧で構成される単語は次のとおりです。予約語、コマンドの最初の単語の場合にのみ特別です。
Ksh は、Bourne シェルの互換性のない拡張で中括弧拡張を実装します。をオフにしてこれを行うことができますset +B
。 Bashはこの点でkshを模倣します。 Zsh は中括弧拡張も実装しています。set +I
またはにsetopt ignore_braces
ドラッグできますemulate sh
。これらのシェルは、引数で一般的に使用されているように、{}
単語の部分文字列(たとえば)でも、いずれにしても拡張されません。foo{}bar
find
そしてxargs
。
シングルUnix v2気づく
いくつかの歴史的システムでは、中括弧は制御演算子と見なされます。将来の標準化アクティビティをサポートするには、移植可能なアプリケーションでは、文字自体を表すために引用符で囲まれていない中括弧を使用しないでください。 ISO/IEC 9945-2:1993 規格の今後のバージョンでは、これを要求する可能性があり、
{
トークンは頻繁に使用される構成により特別なケースが免除される可能性がありますが、}
制御演算子として別々に処理することができます。{}
find
{}
このメモは、この標準の後続のバージョンから削除されました。の例find
{}
次のように引用されていない目的があります。の例xargs
。{}
歴史的なBourneシェルを参照する必要があるかもしれませんが、今は非常に古いレガシーシステムです。
私が持っているcshの実装(OpenBSD 4.7、Debian の BSD csh、tcsh)すべてが拡張され{foo}
ましたが無視されfoo
ました{}
。