100万個までのファイルを含むディレクトリがあり、特定のパターンを検索する必要があります。私はすべてのファイルに対してそれを行う方法を知っています:
find /path/ -exec grep -H -m 1 'pattern' {} ;
完全な出力は望ましくありません(遅すぎる)。いくつかの最初のヒットはOKなので、行数を制限しようとしました:
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
への引数を提供するなど) head -n
に似ています )?
承認された回答:
すでにGNU拡張機能を使用しているため(-quit
、-H
、-m1
)、GNU grep
を使用することもできます の-r
オプションと--line-buffered
そのため、一致が見つかるとすぐに出力されるため、6行目を書き込むとすぐにSIGPIPEが強制終了される可能性が高くなります。
grep -rHm1 --line-buffered pattern /path | head -n 5
find
を使用 、おそらく次のようなことをする必要があります:
find /path -type f -exec sh -c '
grep -Hm1 --line-buffered pattern "[email protected]"
[ "$(kill -l "$?")" = PIPE ] && kill -s PIPE "$PPID"
' sh {} + | head -n 5
つまり、grep
をラップします sh
で (まだ少数のgrep
を実行したい 可能な限り呼び出し、したがって{} +
)、sh
があります 親を殺す(find
)grep
の場合 SIGPIPEで死ぬ。
別のアプローチは、xargs
を使用することです。 -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
ファイルごとに複数のコマンドを実行するため、非常に非効率的です。
関連:Ubuntu – Ubuntu20.04でamdGPUのファン速度をロックする方法は?