
ちょっと奇妙かもしれませんし、これを行うための他のツールもあるかもしれませんが、まあ...
私は、ある文字列を含むすべてのファイルを見つけるために、次の古典的な bash コマンドを使用しています。
find . -type f | xargs grep "something"
複数の深さに渡って、多数のファイルがあります。「何か」の最初の出現で十分ですが、find は検索を続行し、残りのファイルを完了するのに長い時間がかかります。私がやりたいのは、grep から find に「フィードバック」のようなものを返すことで、find がそれ以上のファイルの検索を停止できるようにすることです。そのようなことは可能ですか?
答え1
単に検索範囲内に留めてください:
find . -type f -exec grep "something" {} \; -quit
仕組みは以下のとおりです:
が true の-exec
場合、 は機能します。また、 が一致すると は (success/true)を返すため、 がトリガーされます。-type f
grep
0
-exec grep "something"
-quit
答え2
find -type f | xargs grep e | head -1
はまさにそれを行います。 がhead
終了すると、パイプの中間の要素に「壊れたパイプ」信号が通知され、順番に終了して に通知しますfind
。次のような通知が表示されます。
xargs: grep: terminated by signal 13
これはこれを裏付けています。
答え3
ツールを変更せずにこれを行うには: (私は xargs が大好きです)
#!/bin/bash
find . -type f |
# xargs -n20 -P20: use 10 parallel processes to grep files in batches of 20
# grep -m1: show just on match per file
# grep --line-buffered: multiple matches from independent grep processes
# will not be interleaved
xargs -P10 -n20 grep -m1 --line-buffered "$1" 2> >(
# Error output (stderr) is redirected to this command.
# We ignore this particular error, and send any others back to stderr.
grep -v '^xargs: .*: terminated by signal 13$' >&2
) |
# Little known fact: all `head` does is send signal 13 after n lines.
head -n 1