特定のパターンを検索するために必要な約1Mファイルを含むディレクトリがあります。私はすべてのファイルに対してこれを行う方法を知っています。
find /path/ -exec grep -H -m 1 'pattern' \{\} \;
完全な出力は必要ありません(遅すぎます)。最初の数回クリックすると効果があったので、行数を制限してみました。
find /path/ -exec grep -H -m 1 'pattern' \{\} \; | head -n 5
これにより5本の線が生成され、次に
find: `grep' terminated by signal 13
そしてfind
働き続けなさい。これは説明しやすいです。ここ。私はquit
行動を試みました:
find /path/ -exec grep -H -m 1 'pattern' \{\} \; -quit
これは最初の一致のみを出力します。
検索出力を特定の数の結果に制限できますか(例:quit
simple toに似たパラメータを提供head -n
)。
ベストアンサー1
-quit
すでにGNU拡張(、、、-H
)を使用しているので、GNUオプションを使用して一致を見つけるとすぐに出力すること-m1
もできます。したがって、一致が見つかると、SIGPIPEによって終了される可能性が高くなります。 6行目は次のとおりです。grep
-r
--line-buffered
grep -rHm1 --line-buffered pattern /path | head -n 5
の場合、find
次のことが必要になる場合があります。
find /path -type f -exec sh -c '
grep -Hm1 --line-buffered pattern "$@"
[ "$(kill -l "$?")" = PIPE ] && kill -s PIPE "$PPID"
' sh {} + | head -n 5
つまり、ラップしてgrep
(まだ可能な限り少ない呼び出しをsh
実行したいので、はい)、SIGPIPEのために終了したら、その親()を終了します。grep
{} +
sh
find
grep
別のアプローチは、生成されたコマンドが信号のために終了したときにすぐにxargs
as.exitを使用することです-exec {} +
。xargs
find . -type f -print0 |
xargs -r0 grep -Hm1 --line-buffered pattern |
head -n 5
(-r
そして-0
GNU拡張です)。grep
破損したパイプへの書き込みが行われると、両方が終了し、grep
次に何かが印刷されたときにもそれ自体が終了します。走ると、より早く起こります。xargs
find
find
stdbuf -oL
POSIXのバージョンは次のとおりです。
trap - PIPE # restore default SIGPIPE handler in case it was disabled
RE=pattern find /path -type f -exec sh -c '
for file do
awk '\''
$0 ~ ENVIRON["RE"] {
print FILENAME ": " $0
exit
}'\'' < "$file"
if [ "$(kill -l "$?")" = PIPE ]; then
kill -s PIPE "$PPID"
exit
fi
done' sh {} + | head -n 5
ファイルごとに複数のコマンドを実行するため、非常に非効率的です。