
find
マニュアルページによると、ORは式と共に使用されます。
expr1 -o expr2
Or; expr2 is not evaluated if expr1 is true.
-print
それでは、この例のような作業でも機能するのはなぜですか?
find . -type d -exec sh -c 'printf "%s/\n" "$0"' {} \; -or -print
答え1
行動は表現また副作用のある表現でもあります。 (POSIXアクションは言及さえありません。 )
の-exec
場合、式の値は実行されたコマンドの状態を反映します。成功した場合(終了コード0で示されている)、式の値はtrue、そうでない場合はfalseです。だから
find . -type d -exec sh -c 'printf "%s/\n" "$0"' {} \; -or -print
現在のディレクトリで繰り返されます。ディレクトリの下にあるファイルの場合は実行されますsh
(printf
ディレクトリの後にスラッシュがあります)。他のすべての場合は、ジョブが実行されfind
ますprint
。-or
ここで重要な値はsではなくsです。-type d -exec ...
-print
-type d
-exec
詳しくは、find
優先順位の規則は次のとおりです。
find . -type d -exec sh -c 'printf "%s/\n" "$0"' {} \; -or -print
次のように明示的に作成できます。
find . \( -type d -exec sh -c 'printf "%s/\n" "$0"' {} \; \) -or -print
接続式-or
は次のとおりです。
-type d -exec sh -c 'printf "%s/\n" "$0"' {} \;
そして
-print
完全な表現セット(用語の一般的な意味では、つまりディレクトリなどを含む)、左から始まる:
-type d
現在のファイルがディレクトリの場合はtrueと評価され、それ以外の場合はfalseと評価されます。-exec ...
前の式がtrueの場合、現在のファイルがディレクトリかどうかを評価します。評価には現在のファイルを引数として実行するアクションが含まれ、sh -c 'printf "%s/\n" "$0"'
結果はステータス0で終了した場合はtrue、そうでない場合はfalseです。sh
-print
-type
前の式(および)の結果が次のように-exec
評価されます。間違った、つまり現在のファイルがディレクトリではないか、ディレクトリですがsh
失敗しました。
答え2
小さなスイッチは-o
出力を完全に切り替えます。 2つのファイル(「111」と「2 2」を含む)と「test *」に一致する2つの認識できないディレクトリがあります。
$ find . -name 'test*' \( -exec cat {} \; -print \) 2>/dev/null
1111 111 11111
./test
2 2 2 2
./test2
$ find . -name 'test*' \( -exec cat {} \; -o -print \) 2>/dev/null
./testdir
./testdir2
1111 111 11111
2 2 2 2
最初の項目は(暗黙的に)成功するたびに実行されます-a
。ディレクトリの場合、エラーメッセージはリダイレクトされ、-printは「評価」されません。つまり、論理ANDチェーンが切断されます。-print
-exec
2番目の項目(「cat OR print」)は、失敗した場合にのみ印刷されます。
プラムの例は人間の発見の中に埋もれていますが、私はそれを理解するのが難しいです。
find . -path ./src/emacs -prune -o -print
これらのAND-ORリストは難しく、優先順位が重要であるため、これらのクールなリストはすぐに必要です\(parens\)
。 Findのコマンドラインは見苦しいですが、クエリは素晴らしいです!