次のファイルを検討してください。
$ find findtest
findtest
findtest/test1
findtest/test1/start.ksh
findtest/test2
findtest/test2/start.ksh
findtest/test3
findtest/test3/start.ksh
findtest/test4
findtest/test4/start.ksh
{}
私の質問は通話中の使用に関するものです-exec
。結果ファイルを指定すると、期待どおりに機能します。
$ find findtest -name test[1-4] -exec ls -d {} \;
findtest/test1
findtest/test2
findtest/test3
findtest/test4
ただし、パスで使用すると拡張されないようです。
$ find findtest -name test[1-4] -exec md5sum {}/start.ksh \;
md5sum: {}/start.ksh: No such file or directory
md5sum: {}/start.ksh: No such file or directory
md5sum: {}/start.ksh: No such file or directory
md5sum: {}/start.ksh: No such file or directory
を使用してfind -type d -exec
下位層ファイルにアクセスするには?次のループが利用可能であることを知っていますが、for
1回の呼び出しで実行できるかどうか疑問に思います。find
$ for f in $(find findtest -name test[1-4]); do md5sum "$f"/start.ksh; done
d41d8cd98f00b204e9800998ecf8427e findtest/test1/start.ksh
d41d8cd98f00b204e9800998ecf8427e findtest/test2/start.ksh
d41d8cd98f00b204e9800998ecf8427e findtest/test3/start.ksh
d41d8cd98f00b204e9800998ecf8427e findtest/test4/start.ksh
答え1
これfind コマンドの POSIX 標準スタンドアロン{}をファイル名に変更し、最初の名前を変更するだけです。使用すると、{}/start.ksh
未指定の動作が発生する可能性があります。
2 文字の「{}」のみを含む引数は、集約されたパス名のセットで置き換える必要があり、各パス名は集計順序に従って呼び出しユーティリティに別々の引数として渡されます。複数のパス名のセットのサイズは、ユーティリティの実行によってシステムの{ARG_MAX}制限を超えないように制限する必要があります。 2 文字の「{}」のみを含む引数が複数ある場合、動作は指定されません。
Utility_nameまたは引数文字列に「{}」2文字の代わりに「{}」2文字が含まれている場合、findがその2文字を置き換えるか、変更されていない文字列を使用するかは実装によって定義されます。
Solaris findを使用して目的の操作を実行する1つの方法は、次のコマンドを使用することです。
find findtest -name "test[1-4]" -exec sh -c 'md5sum $1/start.ksh' foo {} \;
より速い方法は次のとおりです。
find findtest -name "test[1-4]" -exec sh -c 'for i; do md5sum "$i/start.ksh"; done' foo {} +
答え2
- 実際、シェルを
test[1-4]
呼び出す前にシェルが拡張されますfind
。あなたはそれを逃げなければなりません。'…'
{}
別のタグの場合のみパターンと見なされます。
-exec
それ自体は費用がかかることが多く、尾引きと一緒に使用するか、+
餌を与えるのを避けることをお勧めしますxargs
。
私はこのようなforループを使用できることを知っていますが、一度のfind呼び出しで実行できるかどうか疑問に思います。
find findtest -name 'test[1-4]' -print0 | xargs -0I{} -- md5sum '{}/start.ksh'
- 効率的なmd5sum
作業 - すべてのファイル名を一度に提供します。