如何限制 grep 返回的结果数量?

253

我希望从grep命令中最多输出10行结果。

我不想让我的计算机过度运转,我想要它在grep找到10个结果后停止。这种操作是否可行?


1
在您的情况下,您不希望计算机工作太努力。但如果只是人类可读性问题,您可以通过管道使用 less。这将填充屏幕,您可以按 ENTER 查看更多行,并按 q 退出:grep "SomeText" somefile.csv | less - SilentSteel
6个回答

337

-m选项可能是你要找的:

grep -m 10 PATTERN [FILE]

man grep 中获取:

-m NUM, --max-count=NUM
        Stop reading a file after NUM matching lines.  If the  input  is
        standard  input  from a regular file, and NUM matching lines are
        output, grep ensures that the standard input  is  positioned  to
        just  after the last matching line before exiting, regardless of
        the presence of trailing context lines.  This enables a  calling
        process  to resume a search.

注意:grep在找到指定数量的匹配项后就会停止读取文件!


3
嗨,我试过了,基本上它可以工作,但似乎grep在找到前10行后并没有停止思考,看起来它继续思考并“使用我的CPU”,只是没有打印出来,这正确吗?谢谢。 - Jas
6
@Jason:看起来情况并非如此:在我的笔记本上,使用“-m 1” grep 对一个有 1000 万行的文件进行搜索只需花费 0.005 秒,而不使用则需要 1.579 秒。请您参考。 - Grégoire
3
将输出通过管道传递给tail通常是可行的,但如果你使用带上下文的grep,比如grep -A10 PATTERN,就会出现问题。使用tail会截断上下文而不是结果数量。这个答案符合我的需求。 - dimo414
1
-m 10 是一个在搜索多个文件时起作用的选项!如果第一个文件中有太多匹配项,使用管道命令显示前几行将不会显示后续文件中的匹配项。谢谢! - Julien
2
在旧版本的grep中(例如Ubuntu 16.04上可以找到的2.25版本),-m选项与-A/-B/-C选项冲突,仅输出m行而不是由-A/-B/-C定义的内容。新版本没有这个问题(在Arch上测试了3.1版本)。 - Nikolaos Kakouros
显示剩余2条评论

73

另一个选择是直接使用head命令:

grep ...parameters... yourfile | head

这不需要搜索整个文件-当找到第十行匹配的行时,它将停止。使用这种方法的另一个优点是,即使您使用了带有-o选项的grep,它也最多返回10行。

例如,如果文件包含以下行:

112233
223344
123123

这是输出结果的不同之处:

$ grep -o '1.' yourfile | head -n2
11
12

$ grep -m2 -o '1.'
11
12
12

使用 head 只返回所需的 2 个结果,而 -m2 返回了 3 个。


3
请注意,当使用grep-A-B一起时(因此不仅搜索结果(-o),而且还要搜索上下文),您不能使用| head管道。在这种情况下,您只能使用-m告诉grep返回具有结果的行数。 - Attila O.
22
使用"head"命令并不能真正阻止grep命令完全扫描整个文件,而使用grep命令中的"-m"选项可以实现此功能。 - Maic López Sáenz

7

Awk方法:

awk '/pattern/{print; count++; if (count==10) exit}' file

4

针对两种情况:

  1. 我只想要总共n个结果,而不是每个文件n个结果,grep -m 2是每个文件的最大匹配次数。
  2. 我经常使用git grep,它不带有-m选项。

在这些情况下,一个好的替代方案是使用grep | sed 2q来在所有文件中找到前两个匹配项。Sed文档:https://www.gnu.org/software/sed/manual/sed.html


“grep -m 2” 是每个文件的最大匹配次数。这似乎取决于 grep 版本。我想要这种行为,但在 macOS 上使用“grep(BSD grep)2.5.1-FreeBSD”时没有得到它。我在 macOS 上使用 homebrew 安装了 grep(brew install grep && ggrep foo),并且该版本(“ggrep(GNU grep)3.7”)表现出这种行为。 - David Winiecki

1

Emily在她的答案(2020年中期)中提到:

我经常使用git grep,它不需要-m

实际上,从Git 2.38(2022年第三季度)开始:
"git grep -m<max-hits>"(手册)是一种限制每个文件显示的匹配项数量的方法。

这意味着在Git存储库中进行搜索时,可以使用git grep -m作为grep的替代方法。

查看 提交 68437ed(2022年6月22日),作者为 Carlos López (00xc)
(合并自 Junio C Hamano -- gitster --提交 8c4f65e,2022年7月13日)

grep:添加 --max-count 命令行选项

签名:Carlos López 00xc@protonmail.com

这个补丁增加了一个命令行选项,类似于GNU grep(1)的-m / --max-count,用户可能已经习惯了使用它。
这使得在保持其他选项的功能(如-C(显示代码上下文)或-p(显示包含函数))的同时限制输出中显示的匹配数量成为可能,这将很难通过shell管道(例如head(1))实现。
现在,git grep在其man页面中包括了这个选项。
"-m " 表示限制每个文件的匹配数量,"--max-count " 同样表示限制每个文件的匹配数量。当使用“-v”或“--invert-match”选项时,搜索会在指定数量的非匹配后停止。-1的值将返回无限结果(默认值);0的值将立即退出并显示非零状态。

0
使用tail:
#dmesg 
...
...
...
[132059.017752] cfg80211:   (57240000 KHz - 65880000 KHz @ 2160000 KHz), (N/A, 4000 mBm)
[132116.566238] cfg80211: Calling CRDA to update world regulatory domain
[132116.568939] cfg80211: World regulatory domain updated:
[132116.568942] cfg80211:   (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
[132116.568944] cfg80211:   (2402000 KHz - 2472000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
[132116.568945] cfg80211:   (2457000 KHz - 2482000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
[132116.568947] cfg80211:   (2474000 KHz - 2494000 KHz @ 20000 KHz), (300 mBi, 2000 mBm)
[132116.568948] cfg80211:   (5170000 KHz - 5250000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
[132116.568949] cfg80211:   (5735000 KHz - 5835000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
[132120.288218] cfg80211: Calling CRDA for country: GB
[132120.291143] cfg80211: Regulatory domain changed to country: GB
[132120.291146] cfg80211:   (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
[132120.291148] cfg80211:   (2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A, 2000 mBm)
[132120.291150] cfg80211:   (5170000 KHz - 5250000 KHz @ 40000 KHz), (N/A, 2000 mBm)
[132120.291152] cfg80211:   (5250000 KHz - 5330000 KHz @ 40000 KHz), (N/A, 2000 mBm)
[132120.291153] cfg80211:   (5490000 KHz - 5710000 KHz @ 40000 KHz), (N/A, 2700 mBm)
[132120.291155] cfg80211:   (57240000 KHz - 65880000 KHz @ 2160000 KHz), (N/A, 4000 mBm)
alex@ubuntu:~/bugs/navencrypt/dev-tools$ dmesg | grep cfg8021 | head 2
head: cannot open ‘2’ for reading: No such file or directory
alex@ubuntu:~/bugs/navencrypt/dev-tools$ dmesg | grep cfg8021 | tail -2
[132120.291153] cfg80211:   (5490000 KHz - 5710000 KHz @ 40000 KHz), (N/A, 2700 mBm)
[132120.291155] cfg80211:   (57240000 KHz - 65880000 KHz @ 2160000 KHz), (N/A, 4000 mBm)
alex@ubuntu:~/bugs/navencrypt/dev-tools$ dmesg | grep cfg8021 | tail -5
[132120.291148] cfg80211:   (2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A, 2000 mBm)
[132120.291150] cfg80211:   (5170000 KHz - 5250000 KHz @ 40000 KHz), (N/A, 2000 mBm)
[132120.291152] cfg80211:   (5250000 KHz - 5330000 KHz @ 40000 KHz), (N/A, 2000 mBm)
[132120.291153] cfg80211:   (5490000 KHz - 5710000 KHz @ 40000 KHz), (N/A, 2700 mBm)
[132120.291155] cfg80211:   (57240000 KHz - 65880000 KHz @ 2160000 KHz), (N/A, 4000 mBm)
alex@ubuntu:~/bugs/navencrypt/dev-tools$ dmesg | grep cfg8021 | tail -6
[132120.291146] cfg80211:   (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
[132120.291148] cfg80211:   (2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A, 2000 mBm)
[132120.291150] cfg80211:   (5170000 KHz - 5250000 KHz @ 40000 KHz), (N/A, 2000 mBm)
[132120.291152] cfg80211:   (5250000 KHz - 5330000 KHz @ 40000 KHz), (N/A, 2000 mBm)
[132120.291153] cfg80211:   (5490000 KHz - 5710000 KHz @ 40000 KHz), (N/A, 2700 mBm)
[132120.291155] cfg80211:   (57240000 KHz - 65880000 KHz @ 2160000 KHz), (N/A, 4000 mBm)
alex@ubuntu:~/bugs/navencrypt/dev-tools$ 

您可以通过在编辑器中点击类似“{}”的图标来设置“代码格式化”。 - peterh
提供更易读的示例比冗长的代码行更有用。 - Putnik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接