在 Unix 提示符下,如何从与模式匹配的文件中提取可变数量的行(可能包括空行)?

Posted

技术标签:

【中文标题】在 Unix 提示符下,如何从与模式匹配的文件中提取可变数量的行(可能包括空行)?【英文标题】:At the Unix prompt, how do you pull a variable number of lines (which may include a blank line) from a file matching a pattern? 【发布时间】:2019-11-16 23:20:48 【问题描述】:

我的文件中有多条消息,每条消息都有一个时间戳。我需要根据时间戳从文件中提取一条消息。有时,消息的内容中会有一个空行。我更喜欢在 AIX 操作系统的 unix 提示符下执行此操作。

我的文件 (er96aa.example) 包含以下信息。我想拉出第二条时间戳为15:56:10.097的消息(应该是一共4行数据)。

07/05/19 15:56:10.091 SOCKETSND MESSAGE LENGTH=338   MESSAGE:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

07/05/19 15:56:10.097 SOCKETSND MESSAGE LENGTH=338   MESSAGE:

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

07/05/19 15:56:10.099 SOCKETSND MESSAGE LENGTH=338   MESSAGE:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

我试过了

  grep -p '15:56:10.097' er96aa.example 

但这只会返回前两行。

我试过了

  grep -p'07/05/19' '15:56:10.097' er96aa.example

但这什么也没返回。

  grep -p'07/05/19'+ '15:56:10.097' er96aa.example   and

  grep -p'07/05/19+' '15:56:10.097' er96aa.example

但这会返回整个文件

我修改了我的文件并将 07/05/19 放在单独的行上,“grep -p'07/05/19' '15:56:10.097' er96aa.example” 确实有效,但不幸的是我没有能够修改我通常使用的文件的格式。

预期输出:

07/05/19 15:56:10.097 SOCKETSND
MESSAGE LENGTH=338   MESSAGE:

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

【问题讨论】:

【参考方案1】:

我无权访问 AIX 机器来测试它,但请尝试:

$ awk '/MESSAGE:/f=0 /15:56:10.097/f=1 f' file
07/05/19 15:56:10.097 SOCKETSND MESSAGE LENGTH=338   MESSAGE:

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

工作原理

默认情况下,awk 一次读取一行文件。我们的脚本使用单个变量f 来确定是否应该打印当前行。

/MESSAGE:/f=0

如果正则表达式 MESSAGE: 出现在当前行,这会将变量 f 设置为 false (0)。

/15:56:10.097/f=1

这将变量f 设置为true (1) 是正则表达式15:56:10.097 出现在当前行。

f

如果f 为真,则打印该行。

【讨论】:

非常感谢约翰!那工作得很好。我特别感谢您解释命令的不同部分。这将使我的工作研究更快。【参考方案2】:

Johns 帖子的一些变体。

awk '/^[0-9]2\/[0-9]2\/[0-9]2/f=0 /^07\/05\/19 15:56:10.097/f=1 f'
07/05/19 15:56:10.097 SOCKETSND MESSAGE LENGTH=338   MESSAGE:

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

这使用确切的日期和时间作为触发器,并将所有行以日期格式开始到下一行。

【讨论】:

感谢 Jotne 的回复。这确实也产生了我需要的结果(在我取出最后一个条件的 ^ 之后)。如果有时间,您能解释一下 2 代表什么吗?我已经使用 AIX 很多年了,但是我在命令行语言方面还没有很有创意。 @SharonR 2 确实意味着重复两次。 [0-9]2[0-9][0-9] 相同,[0-9]3[0-9][0-9][0-9] 相同

以上是关于在 Unix 提示符下,如何从与模式匹配的文件中提取可变数量的行(可能包括空行)?的主要内容,如果未能解决你的问题,请参考以下文章

在 unix/linux shell 中进行模式匹配时,如何使用反向或负通配符?

如何从与某个键匹配的 JSON 对象创建一个数组?

如何根据某些搜索模式在 unix 中为文本文件着色?

glob模式

Python3标准库:fnmatch UNIX式glob模式匹配

从与数组上的查询条件匹配的第一个元素中投影特定字段