我有一个很长的日志来解析,每个事件的日志消息通常需要多行。如果我使用每个事件的硬编码行号,那么我可以使用grep -A $EventLineNumbers
来获取每个事件的整个消息。
现在,例如,我想在一个事件中使用20行消息grep两个数据字段。该事件可能会在日志中记录100次。我想逐行避免进程grep结果,因为如果其中一个事件中没有一个数据字段存在,我将最终从不同的事件和" bundle"中获取数据。它与之前的事件有关。
简而言之,假设我在命令中设置了-A选项,我如何单独处理每个grep?
答案 0 :(得分:0)
对于这种解析,我会使用awk(1)。与grep(1)相比,它允许您轻松使用变量和条件。所以你可以:
如果实际上这些行没有意思,你可以重置状态并跳到下一个有趣的消息。
该命令将比简单的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。