Grep只有第一局并停止


328

我正在使用带有以下参数的grep递归搜索目录,希望仅返回第一个匹配项。不幸的是,它返回的不止一个-实际上是我上次查看时的两个。似乎我有太多争论,尤其是没有得到理想的结果。:-/

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

返回:

Pulsanti Operietur
Pulsanti Operietur

也许grep不是执行此操作的最佳方法?你告诉我,非常感谢。

Answers:


510

-m 1表示返回任何给定文件中的第一个匹配项。但是它仍然会继续在其他文件中搜索。另外,如果同一行中有两个或多个匹配项,则将全部显示。

您可以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 2012年

3
正是我需要的。我的模式在同一行上被两次发现,因此grep -m 1返回了两个实例。|head -1解决了!
哈珀维尔,2015年

6
@Chris_Rands的确切行为取决于您在其中运行的外壳。head遇到第一行时将立即退出。在退出磁头之后,grep将在下次尝试写入时退出。一些外壳程序将等到管道中的所有元素完成,一些外壳程序将在管道中的最后一个程序退出后立即导致整个管道关闭。
–'puhlen

1
@ 3Qn,我不明白您的评论:first not first from result。此答案将在任何文件中打印第一个匹配项并停止。您还期望什么?
mvp

31

您可以将grep结果headstdbuf结合使用。

注意,为了确保在第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

一旦head消耗了1条线,它就会终止并grep会收到,SIGPIPE因为它head在消失时仍会输出一些内容给管道。

假定没有文件名包含换行符。


我试图采用这种解决方案中大量使用的存档文件中搜索xargsfind . -name '*.gz' | xargs -I '{}' stdbuf -oL zgrep -al 'pattern' {} | head -n 1。但是,这不会在第一个比赛中终止。有什么建议吗?
DKroot

1
不会grep--line-buffered选项防止开销缓冲,而无需调用额外的效用?
大卫,

23

我的类似grep的程序ack有一个-1选项,该选项会在任何地方的第一个匹配项处停止。它也支持-m 1@mvp所引用的。我把它放在那里是因为如果我正在搜索一棵大的源代码树以找到仅存在于一个文件中的已知内容,则无需找到它并且必须按Ctrl-C。


所以你会说ack比grep快?我也很关心速度因素。
蒂姆·卡姆

1
ack可能比grep快,具体取决于您要搜索的内容。请注意,ack与搜索源代码有关。如果您要搜索常规文件,那么这样做至少在ack 1.x中不太好。继续阅读有关ack的信息,看看它是否适合您的需求。
安迪·莱斯特

2
我一直在使用确认了很长一段时间,但最近切换到银搜索我觉得这是更快确认
guy.gc

我认为这应该是唯一的答案,因为OP表示他希望使用grep完成此操作,但另一个答案使用head(当然是两项工作),但是有些嵌入式/自行创建的环境使用的工具最少,其中grep很常见,而tail /头不是。
Areeb Soo Yasir '04 -4-20

值得一提的是,这ag可能很快,但是它没有-1在这种情况下有用的选项
jja


2

单个衬板,使用find

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

6
这将非常慢,因为find会为找到的每个文件生成grep副本。grep -r工作速度更快-它只有一个副本可以进行目录遍历。
mvp

真正; 尽管可以自定义find,使其仅对过滤后的结果进行操作,这可以使操作比全面处理grep快得多。取决于上下文。
Yam Marcovic
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.