我想在日志文件中列出所有错误消息,如下所示,并提供错误的完整描述。
00:02:00:00 Here I found an ERROR
00:02:00:00 Description
00:02:00:00 Description
00:02:00:00 This is a System Error (DESCRIPTION_ENDS)
00:02:00:00
00:02:00:00 Some General Message
00:02:00:00 Some General Message
00:02:00:00
00:02:00:00 Again got an ERROR
00:02:00:00 Description
00:02:00:00 Description
00:02:00:00 Description
00:02:00:00 Description
00:02:00:00 This is a Critical Error (DESCRIPTION_ENDS)
00:02:00:00
00:02:00:00 Some General Message
00:02:00:00 Some General Message
我正在寻找一个逻辑,可能使用grep或sed,它只显示带描述的ERROR块。
输出:
00:02:00:00 Here I found an ERROR
00:02:00:00 Description
00:02:00:00 Description
00:02:00:00 This is a System Error (DESCRIPTION_ENDS)
00:02:00:00 Again got an ERROR
00:02:00:00 Description
00:02:00:00 Description
00:02:00:00 Description
00:02:00:00 Description
00:02:00:00 This is a Critical Error (DESCRIPTION_ENDS)
为了实现这一点,我能想到的唯一逻辑是读取整个文件并打印出有" ERROR"直到包含" DESCRIPTION_ENDS"。
的行可以使用grep或sed实现吗?如果没有,unix中的任何其他命令,可以通过它来实现吗?
答案 0 :(得分:1)
awk
是一个选项:
awk '/ERROR/ {on=1} on==1 {print} /DESCRIPTION_ENDS/ {on=0; print ""}' data
说明:有3条规则,awk
按顺序应用它们。
/ERROR/ {on=1}
模式匹配,则第一个(awk
)设置on
变量ERROR
。on==1 {print}
变量awk
,则第二行(on
)会打印当前行。/DESCRIPTION_ENDS/ {on=0; print ""}
)清除awk
变量on
,如果该行符合DESCRIPTION_ENDS
模式,则插入一个空行。答案 1 :(得分:1)
awk
解决方案:
awk '/ERROR/{f=1};f;/(System|Critical) Error/{print "";f=0}' infile
检查http://klashxx.github.io/awk-between-two-patterns/以获取详细说明。
<强>结果
00:02:00:00 Here I found an ERROR
00:02:00:00 Description
00:02:00:00 Description
00:02:00:00 This is a System Error (DESCRIPTION_ENDS)
00:02:00:00 Again got an ERROR
00:02:00:00 Description
00:02:00:00 Description
00:02:00:00 Description
00:02:00:00 Description
00:02:00:00 This is a Critical Error (DESCRIPTION_ENDS)
还有一个sed
替代品(根据我的口味不太灵活):
sed -nr '/\s+ERROR/,/\s+Error\s+\(/p' infile
将输出:
00:02:00:00 Here I found an ERROR
00:02:00:00 Description
00:02:00:00 Description
00:02:00:00 This is a System Error (DESCRIPTION_ENDS)
00:02:00:00 Again got an ERROR
00:02:00:00 Description
00:02:00:00 Description
00:02:00:00 Description
00:02:00:00 Description
00:02:00:00 This is a Critical Error (DESCRIPTION_ENDS)
答案 2 :(得分:1)
这实际上只是一个单行,但为了便于阅读,它已经扩展了一点。它依赖于PERLOP(1)中定义的触发器范围运算符,以线路方式匹配块的开始和结束。例如:
$ perl -ne 'print if /ERROR/.../DESCRIPTION_ENDS/;
print "\n" if /DESCRIPTION_ENDS/;
' /tmp/corpus
00:02:00:00 Here I found an ERROR
00:02:00:00 Description
00:02:00:00 Description
00:02:00:00 This is a System Error (DESCRIPTION_ENDS)
00:02:00:00 Again got an ERROR
00:02:00:00 Description
00:02:00:00 Description
00:02:00:00 Description
00:02:00:00 Description
00:02:00:00 This is a Critical Error (DESCRIPTION_ENDS)
额外的print语句实际上只是在你的块之间创建段落以提高可读性,并且在每种语言的段落模式打开时使其更适合Perl,Awk或Ruby使用。如果需要,这将简化进一步处理。
答案 3 :(得分:0)
我知道这不是您想要的(但这更简单),但您可以尝试搜索错误并使用-A选项为grep提供一些上下文。
grep -A 5 "ERROR" myFile
我意识到我已经将上下文硬编码到固定的5行,这可能无法解决您的问题,但如果您所做的只是手动搜索日志文件,那么它可能已经足够了。
如果你的描述有一些格式,那么你可以将结果输入第二个grep,所以它只包含你想要的行。