尝试用awk从我的日志中隔离一个块,请帮忙!

时间:2011-02-18 01:31:45

标签: awk

我正在尝试编写一个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

常规块看起来完全相同,但没有错误:部分显然。

希望这更清楚,再次感谢!

4 个答案:

答案 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

-------

Running at ideone here

修改

关于在错误记录之前有有时空记录的评论,您可以通过使用以下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选项是将文件一次传递给文件的神奇咒语。