私は通常Solarisを使用していませんが、今日はシェルを使用して識別されたファイルに対処するためにfindコマンドを書く必要がありました。私はこれらの{}
文字が置き換えられておらず、代替文字が見つからないことを発見しました。
たとえば、
bash-3.2# find / -exec sh -c "echo {}" \;
{}
これにより、ファイル名の代わりに各ファイルが印刷されます。
答え1
これを使用する唯一の標準的な方法は、find -exec …
別のパラメータとして渡すことです。{}
パラメータが含まれる場合の動作は{}
標準化されていません。あなたは{}
部分文字列内で置き換えるGNUの動作に精通しているようです。find
Solarisのコマンドは{}
引数に{}
。
GNUの振る舞いは特に役に立たず、時には迷惑なこともあります。引数にファイル名を置き換えるのは脆弱だからです。制限がわからない場合は、ファイル名の開始と終了の場所を知る方法はありません。たとえば、GNU findを使用すると、find / -exec sh -c "echo {}" \;
実際にいいえ通常はファイル名を印刷します。シェル特殊文字が含まれていない場合にのみファイル名を印刷します。というファイルを含むディレクトリで実行している場合は、;rm -r ~
ファイルに別れを告げてください。
シェルを呼び出す安定した移植可能な方法は、find -exec
ファイル名をシェルに引数として渡すことです。
find … -exec sh -c 'echo "$0"' {} \;
ほとんどの場合、パラメータをまとめて渡してシェルで繰り返すことができます。少し早いですね。シェルコードの後の最初のパラメータ$0
は"$@"
。
find … -exec sh -c 'for x; do echo "$x"; done' _ {} +
また、見ることができますスペースやその他の特殊文字が原因でシェルスクリプトが停止するのはなぜですか?
答え2
マニュアルページと標準で指定されているように、{}
別々のパラメータにする必要があります。
find / -exec sh -c 'echo $1' dummy '{}' \;
期待どおりに動作します。
dummy
シェルは、sh -c cmd
コマンドパラメータが追加された後に最初のパラメータを割り当て、次のパラメータに$0
なるため、このパラメータが必要であることに注意してください$1
。