使用grep获取文件中的最后一个匹配项


58

使用grep仅获取文件中正则表达式的最终匹配的最佳方法是什么?

另外,是否可以从文件末尾而不是开头开始grepping,并在找到第一个匹配项时停止?

Answers:


85

你可以试试

grep pattern file | tail -1

要么

tac file | grep pattern | head -1

要么

tac file | grep -m1 pattern

20
tac file | grep -m 1 pattern
丹尼斯·威廉姆森

1
加上我想grep -n在实际文件中获得行号()的附加约束,我认为tac必须避免很多事情,除非我想对进行减法wc -l。否则,tacgrep -m1使一个很大的意义。
尼克·美林

1
我希望看到一个性能更高的版本,因为我正在尝试搜索20GB的文件。
杰夫

@DennisWilliamson的答案要好得多,因为grep它将在第一场比赛后停止工作。不带-m 1grep将首先找到文件中所有匹配的模式,然后head仅显示第一个-效率低得多。丹尼斯,请考虑将其发布在单独的答案中!
吉拉德·马亚尼

1

对于在Unix / Linux / Mac / Cygwin中使用巨大文本文件的人。如果您使用Windows,请检查有关Windows中Linux工具的信息:https ://stackoverflow.com/questions/3519738/what-is-the-best-way-to-use-linux-utilities-under-windows 。

可以遵循此工作流程来获得良好的性能:

  1. 用gzip压缩
  2. 使用zindex(在github:https : //github.com/mattgodbolt/zindex上)使用适当的密钥为文件建立索引
  3. zq从包中查询带有索引的文件。

引用自其github自述文件:

创建一个索引

需要告诉zindex每行的哪一部分构成索引。可以通过正则表达式,按字段或通过外部程序将每行用管道传递来完成。

默认情况下,当要求索引file.gz时,zindex会创建file.gz.zindex的索引。

例:

在与数字正则表达式匹配的行上创建索引。捕获组指示要索引的部分,选项显示每行都有唯一的数字索引。

$ zindex file.gz --regex 'id:([0-9]+)' --numeric --unique

示例:在CSV文件的第二个字段上创建索引:

$ zindex file.gz --delimiter , --field 2 

例:

在文档根目录的action数组中的任何项中的JSON字段orderId.id上创建索引(需要jq)。jq查询创建一个包含所有orderId.ids的数组,然后将它们与一个空格连接起来,以确保通过管道传递给jq的每一行都创建一条输出行,其中多个匹配项之间用空格分隔(这是默认的分隔符)。

$ zindex file.gz --pipe "jq --raw-output --unbuffered '[.actions[].orderId.id] | join(\" \")'" 

查询索引

zq程序用于查询索引。它具有压缩文件的名称和查询列表。例如:

$ zq file.gz 1023 4443 554 

也可以按行号输出,以便从文件中打印行1和行1000:

$ zq file.gz --line 1 1000

1

我一直在使用cat(但这会使它变长一些): cat file | grep pattern | tail -1

我会怪我爱猫的大学的Linux管理课程老师:))))

-您无需在抓取文件之前先整理文件。grep pattern file | tail -1而且效率更高。


6
这只是Cakemox回答的第一部分,除非更糟。
augurar

它可以工作,但是可以执行不必要的步骤。对于轻型用途,此解决方案效果很好,但效果不佳。原因是因为您不需要cat将文件传输到grep。您可以grep直接通过搜索文件grep pattern file(然后使用tail返回最后的结果),如Cakemox的答案一样。
jvriesem
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.