最初の一致のみをgrepして停止


329

最初の一致のみを返すことを期待して、次の引数を指定してgrepを使用してディレクトリを再帰的に検索しています。残念ながら、それは複数を返します-私が最後に見たとき、実際には2つです。特に望ましい結果が得られない場合、私はあまりにも多くの議論をしているようです。:-/

# grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/directory

戻り値:

Pulsanti Operietur
Pulsanti Operietur

多分これを行うための最良の方法はgrepではありませんか?教えてくれてありがとう

回答:


512

-m 1任意のファイルで最初に一致したものを返すことを意味します。ただし、他のファイルは引き続き検索されます。また、同じ行に2つ以上一致するものがある場合、それらすべてが表示されます。

head -1この問題を解決するために使用できます。

grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/dir | head -1

各grepオプションの説明:

-o, --only-matching, print only the matched part of the line (instead of the entire line)
-a, --text, process a binary file as if it were text
-m 1, --max-count, stop reading a file after 1 matching line
-h, --no-filename, suppress the prefixing of file names on output
-r, --recursive, read all files under a directory recursively

驚くばかり!ありがとうございました。ところで-コマンドに必要な他のすべての引数は必要ですか?そして、もし私が偶然にそれをパイプすることができない場合はどうでしょう(念のため)。
Tim Kamm

2
私はそれらが必要であるとは思いませんが(-r明らかな場合を除いて)、害がないはずです(私は使用しません-a
mvp

3
まさに私が必要としたもの。私のパターンは同じ行で2回見つかりgrep -m 1、このため両方のインスタンスが返されました。|head -1解決しました!
harperville、2015年

6
@Chris_Randsの正確な動作は、実行中のシェルによって異なります。headは、最初の行に到達するとすぐに終了します。grepは、headが終了した後、次に書き込もうとしたときに終了します。パイプラインのすべての要素が終了するまで待機するシェルもあれば、パイプ内の最後のプログラムが終了するとすぐにパイプ全体がシャットダウンするシェルもあります。
プーレン

1
@ 3Qn、コメントを理解できません:first not first from result。この回答は、すべてのファイルで最初の一致を出力して停止します。他に何を期待しましたか?
mvp

31

grep結果をstdbufheadと組み合わせてパイプすることができます。

N番目の一致後に確実に停止するために、出力をバッファリングしないstdbufようにするためにを使用する必要があることに注意grepしてください。

stdbuf -oL grep -rl 'pattern' * | head -n1
stdbuf -oL grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/dir | head -n1
stdbuf -oL grep -nH -m 1 -R "django.conf.urls.defaults" * | head -n1

head1行を消費するとすぐに終了し、なくなったときにまだパイプに何かを出力しているのでgrep受信します。SIGPIPEhead

これは、ファイル名に改行が含まれていないことを前提としています。


このソリューションを採用して、多数のアーカイブファイルをxargs次のように検索しようとしていますfind . -name '*.gz' | xargs -I '{}' stdbuf -oL zgrep -al 'pattern' {} | head -n 1。ただし、これは最初の一致で終了しません。何かアドバイス?
DKroot 2018

1
grep--line-bufferedオプションは、追加のユーティリティを呼び出さずにバッファのオーバーヘッドを防止しないのですか?
デビッド

23

私のgrep-a-likeプログラムにackは、-1どこかで見つかった最初の一致で停止するオプションがあります。-m 1@mvpが参照するものもサポートします。ソースコードの大きなツリーを検索して、1つのファイルだけに存在することがわかっているものを見つける場合、それを見つける必要はなく、Ctrl-Cを押す必要があるので、そこに入れました。


だからあなたはackがgrepより速いと言うでしょう?私はスピードファクターにも本当に関心があります。
Tim Kamm

1
検索する内容によっては、ackがgrepよりも高速になる場合があります。ackはソースコードの検索に関するものであることに注意してください。一般的なファイルを検索したい場合は、少なくともack 1.xでは、それほどうまくいきません。ackについて読んで、ニーズに合うかどうかを確認してください。
アンディレスター

2
私は長い間Ackを使用してきましたが、最近Ackの方が速いことがわかったシルバーサーチャーに切り替えました
guy.gc

OPがgrepでそれを実行したいと思ったので、これが唯一の答えであると思いますが、他の答えはヘッド(もちろん両方の作業)を使用しますが、grepが一般的でテール/頭ではありません。
Areeb Soo Yasir 2017

・ワースはそれが言及ag速いかもしれないが、それはありません持っている-1。この場合に有用であるオプション
JJA

4

現在のディレクトリで特定の単語が見つかった場合に、行全体とファイル名を印刷する場合は、以下のコマンドを使用できます。

grep -m 1 -r "Not caching" * | head -1

2

シングルライナー、以下を使用find

find -type f -exec grep -lm1 "PATTERN" {} \; -a -quit

6
findは見つかったすべてのファイルに対してgrepのコピーを生成するため、これは非常に遅くなります。grep -rはるかに速く動作します-ディレクトリトラバーサルを行う唯一のコピーです。
mvp 2016年

真; ただし、findはフィルター処理された結果のみを操作するようにカスタマイズできます。これにより、catch-all grepよりもはるかに高速に操作できます。コンテキストによって異なります。
Yam Marcovic 2016年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.