我正在尝试编写一个awk脚本,该脚本可以从长日志文件中获取包含单词“error”的块。
基本上这个日志文件包含执行的操作,当其中一个失败时,它会在操作下添加错误行,说明错误。
我可以轻松地隔离错误行只是为了“错误:”执行grep,但我错过了给出的命令,因为它在错误行之前打印,而且我不知道之前有多少行,所以不能随意说“打印单词前面的10行”错误:“
我已经想出了一种方案;每个可以包含错误行的块以相同的方式(“ProcessName”)开始,后跟命令和其他参数,每个参数在不同的行上,最后一行始终是空行。所以我的想法是使用这个块与awk,所以我可以找到“processName”字符串,开始逐个打印行,直到我到达空行,然后通过grep管道打印结果看那里是否有“错误:”这个词;如果有错误,那么我将重定向文件并附加整个块,否则它将继续到下一个块并执行相同的操作。
如果能够完成这项任务,现在真的会有所帮助;因为我真的不知道我怎么能做到这一点;我刚刚看了awk,它似乎是工作的正确工具(我可以为任务编写一个shell脚本),但是如果你认为有更好的方法在shell脚本中执行它,我就是所有的耳朵:))
提前感谢您的帮助!
更新:感谢您的脚本;我有一个来自Dennis的工作,但是如果每个块中有多个错误条目,它会多次打印相同的块;虽然来自bellisarius的例子没有返回任何一行。
我添加了一个示例,说明我的日志是什么样的,当我引入错误时(最后有一个空行,但如果我将文本放在标记代码中则无法添加它):
ProcessName
ID=1231
Command:"ls -l a"
Hash "gkfsmgflsdmgklsdmfldsmfklmdsflkmsdflmsdflkmsdflkmsdfklsdmfklsdmfklmsdfklmsdklfmsdklmflksdmflkdsmfkldsmfkldmslfmdslkfmklsdmflksdmfklsdmfkldmslfkmslfkmsdlkfm"
/filename/compileme.c:20: error: the directory does not exist
/filename/compileme.c:20: error: incorrect parameter
常规块看起来完全相同,但没有错误:部分显然。
希望这更清楚,再次感谢!
答案 0 :(得分:1)
您可以尝试:
BEGIN {flag="no";k=0}
/ProcessName/ {flag="no";k=0}
/ProcessName/,/^$/ {a[k++]=$0;
if(match($0,"error")!= 0) {flag="yes"};
}
/^$/ {if (flag=="yes") {flag="no";
for ( i=0; i<k; i++ ){print a[i]}
print "-------";
};
for ( r in a ){delete a[r]};k=0;
}
测试:
输入:
ProcessName
adasd
asdasd
ProcessName with err
error
salutti
ProcessName no err
aaa
no err
ProcessName
输出:
ProcessName with err
error
salutti
-------
修改
关于在错误记录之前有有时空记录的评论,您可以通过使用以下awk脚本预处理日志文件来解决此问题,该脚本删除错误消息之前的空行:
/^$/ {getline; if($0 !~ /error/) print ""}
{print}
然后在这个输出上运行主脚本。
答案 1 :(得分:0)
下次显示一些示例输入
awk 'BEGIN{RS=""}/ProcessName/ && /Error/' file
$ cat file
ProcessName
adasd
asdasd
ProcessName with err
error
salutti
ProcessName no err
aaa
no err
$ awk 'BEGIN{RS=""}/ProcessName/ && /err/' file
ProcessName with err
error
salutti
ProcessName no err
aaa
no err
答案 2 :(得分:0)
试一试
awk '/ProcessName/{a = $0; next} {a = a RS $0} /error:/{print a}' inputfile
每次看到“ProcessName”时,它会累积行并重置累加器。当它看到“错误:”时,它会打印累加器的内容。
答案 3 :(得分:0)
对于空白行分隔文件,我发现Perl最简单:
perl -00 -ne 'print if /^ProcessName/ && /error/' afile
-00
选项是将文件一次传递给文件的神奇咒语。