web-dev-qa-db-ja.com

「検索」で一致が見つかったかどうかを検出するにはどうすればよいですか?

「検索」で一致が見つかったかどうかを検出する慣用的な手段はありますか?私は現在使用しています

_COUNT=`find ... | wc -l`
if [ "$COUNT" -gt 0 ]; then
_

しかし、これは私には少し間接的に思えます。また、一致が見つかったら検索を停止したいので、時間と労力を無駄にしません。一致するファイルがあるかどうかを知る必要があるだけです。

pdate:目の前のコードなしで質問を書き間違えました:別のケースでは_wc -l_を使用しますが、とにかく見つかったファイルの総数を知る必要があります。一致するものがあるかどうかのみをテストする場合は、if [ -z $(find …) ]を使用していました。

15
Chris Page

GNU findを使用していることがわかっている場合は、 -quit を使用して、最初の一致後に停止します。

移植可能に、findの出力をhead -n 1にパイプします。こうすることで、findは、いくつかの一致の後で(headの入力バッファーがいっぱいになると)パイプが壊れて死んでしまいます。

どちらの方法でも、文字列が空かどうかをテストするためにwcを使用する必要はありません。シェルはそれを独自に実行できます。

if [ -n "$(find … | head -n 1)" ]; then …

-quit アクションを使用して、最初の一致の後に停止できます。これを別のアクション(-printなど)と組み合わせると、何かが見つかったかどうかを判別できなくなります。

たとえば、find ... -print -quitは最初に一致したファイルのパスを出力して終了します。または、-printf 1 -quitを使用して、一致するものがある場合は1を出力し、一致しない場合は何も出力しません。

findの終了ステータスは、検索中にエラーがあったかどうかを反映し、何かが見つかったかどうかを反映していないため、一致するかどうかを確認するために出力を確認する必要があります。

6
cjm

出口0は検索で簡単ですが、出口> 0は通常、エラーでのみ発生するため、困難です。ただし、それを実現することはできます。

if find -type f -exec false {} +
then
  echo 'nothing found'
else
  echo 'something found'
fi

このソリューションはサブシェルを使用するよりもパフォーマンスが高いことに注意してください。 falseの実行は、Dashを実行するよりも確かに高速です。

$ cat alfa.sh bravo.sh charlie.sh delta.sh
find -name non-existing-file -exec false {} +
find -name existing-file -exec false {} +
[ "$(find -name non-existing-file)" ]
[ "$(find -name existing-file)" ]

$ strace dash alfa.sh | wc -l
807

$ strace dash bravo.sh | wc -l
1141

$ strace dash charlie.sh | wc -l
1184

$ strace dash delta.sh | wc -l
1194
4
Steven Penny

あなたはそれをシェル条件にラップすることができます、例えば:

[ "$(find . ...)" '!=' '' ] && echo Found || echo Not found

どこ ...は一致条件です。 -name *.txt

その他の例:

[ "$(find /etc -name hosts)" ] && echo True || echo False
[ ! -z "$(find /etc -name hosts)" ] && echo True || echo False
0
kenorb