我有一个巨大的文件,我想用 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
这允许我们打印最后读取的行(如果它是有趣的),即使它正是我们想要退出的时间戳。