如何单独处理每个grep(带-A选项)结果?不是按行,而是按项目

时间:2016-03-30 18:02:42

标签: bash shell

我有一个很长的日志来解析,每个事件的日志消息通常需要多行。如果我使用每个事件的硬编码行号,那么我可以使用grep -A $EventLineNumbers来获取每个事件的整个消息。

现在,例如,我想在一个事件中使用20行消息grep两个数据字段。该事件可能会在日志中记录100次。我想逐行避免进程grep结果,因为如果其中一个事件中没有一个数据字段存在,我将最终从不同的事件和" bundle"中获取数据。它与之前的事件有关。

简而言之,假设我在命令中设置了-A选项,我如何单独处理每个grep?

2 个答案:

答案 0 :(得分:0)

对于这种解析,我会使用awk(1)。与grep(1)相比,它允许您轻松使用变量和条件。所以你可以:

  1. 匹配表示您感兴趣的一堆行开头的行
  2. 设置变量以记住此状态
  3. 以下流程线,记住相关字段
  4. 当您到达这一行的末尾时,打印格式化的信息
  5. 如果实际上这些行没有意思,你可以重置状态并跳到下一个有趣的消息。

    该命令将比简单的grep更长,但它仍然简洁,您不需要使用完整的编程语言。

答案 1 :(得分:0)

这应该有效:

示例输入:

1
2
3
1
4
5
6
2
4

假设所有块都是3行,并且您希望将块与1匹配。以下代码有效:

echo -e '1\n2\n3\n1\n4\n5\n6\n2\n4' | grep 1 -A2 | awk -v n=3 '{print} NR % 3 == 0 { printf "\0" }' | xargs -0 -n 1 echo -n "WOOT: "

说明:

grep 1 -A2是您找到相关块的表达式。我假设匹配表达式每个块只出现一次。 -A2用于匹配后的两行上下文。

awk -v '{print} NR % 3 == 0 { printf "\0" }'部分指示awk每3行打印一个\ 0字符。再次,针对相关的块大小调整此值。我们需要这个用于下一个命令。

xargs -0 -n1部分执行下一个命令(这将是你的额外过滤器),给它整个块。 -0表示空终止项(一个块),-n1表示只将一个项目传递给下一个命令。

在我的例子中,这将给出以下输出:

WOOT:  1
2
3
WOOT:  1
4
5

意味着每个块只执行一次echo。