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のファン速度をロックする方法は?