具有退出条件的 Grep

具有退出条件的 Grep

我有一个巨大的文件,我想用 grep 的简单过滤器来显示它:

假设这是我的文件:

TIME0 random data
TIME1 random data
TIME2 INTERESTING LINE
TIME3 random data
TIME4 random data
TIME5 random data
TIME6 random data
TIME7 INTERESTING LINE
TIME8 random data
TIME9 random data
TIME10 random data
TIME11 INTERESTING LINE
TIME12 random data

我要显示有趣的线路s:

grep "INTERESTING LINE" myfile

这可行,但文件很大并且包含数百万个有趣的线路s。我只需要最后一个:

tac myfile | grep -m3 "INTERESTING LINE"

这可行,但我如何指定我需要有趣的线路仅在一定时间之后时间字首? (或者tac直到某个时间

例如,对于上面的示例文件,我如何 grep 所有有趣的线路是从我的文件从结束到时间7仅有的? (所以不需要TIME2的有趣台词):

TIME11 INTERESTING LINE
TIME7 INTERESTING LINE

顺序并不重要,我可以接受 ASC 或 DESC 顺序。

重要的是不要扫描整个文件,即从文件末尾开始逐行工作。

我正在寻找一种为 grep 提供退出标准的方法(而不是使用 定义最大结果数-m

答案1

使用sed而不是grep对输入数据的解析进行更多控制:

$ tac file | sed -n -e '/^TIME6 /q' -e '/INTERESTING LINE/p'
TIME11 INTERESTING LINE
TIME7 INTERESTING LINE

这将按照您的建议反转文件tac,并通过 传递反转的数据sed

两种sed表达方式:

  • /^TIME6 /q,一旦我们找到以 开头的行就退出TIME6。您还可以使用/^TIME[0-6] /q或 任何与时间列匹配的表达式,这些表达式太旧而无趣。

  • /INTERESTING LINE/p,打印与给定正则表达式匹配的所有行。

其效果是,只有在我们发现太新的时间戳之前才会读取该文件。解析过程中发现的任何有趣的行都会打印到标准输出。

如果您知道TIME7要搜索的确切时间戳,直到:

$ tac file | sed -n -e '/INTERESTING LINE/p' -e '/^TIME7 /q'
TIME11 INTERESTING LINE
TIME7 INTERESTING LINE

这允许我们打印最后读取的行(如果它是有趣的),即使它正是我们想要退出的时间戳。

相关内容