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

试图用awk从我的日志中隔离一个块,请帮助!,awk,Awk,我正在尝试编写一个awk脚本,它可以从一个长日志文件中获取包含“error”一词的块 基本上,这个日志文件包含执行的操作,当其中一个操作失败时,它会在操作下面添加错误行,指出错误所在 我只需对“error:”执行grep,就可以很容易地隔离错误行,但我缺少给出的命令,因为它是在错误行之前打印的,我不知道之前有多少行,所以不能随意说“打印单词“error:”之前的10行” 我已经想出了一种方案:可能包含错误行的每个块都以相同的方式(“ProcessName”)开始,然后是命令和其他参数,每一个都在

我正在尝试编写一个awk脚本,它可以从一个长日志文件中获取包含“error”一词的块

基本上,这个日志文件包含执行的操作,当其中一个操作失败时,它会在操作下面添加错误行,指出错误所在

我只需对“error:”执行grep,就可以很容易地隔离错误行,但我缺少给出的命令,因为它是在错误行之前打印的,我不知道之前有多少行,所以不能随意说“打印单词“error:”之前的10行”

我已经想出了一种方案:可能包含错误行的每个块都以相同的方式(“ProcessName”)开始,然后是命令和其他参数,每一个都在不同的行上,最后一行总是空行

因此,我的想法是将这个块与awk一起使用,这样我就可以查找“processName”字符串,开始一行一行地打印,直到到达空行,然后通过grep将打印的结果传输到管道中,以查看是否有“error:“在那里;如果有错误,那么我将重定向到一个文件并附加整个块,否则它将继续到下一个块并执行相同的操作

现在,如果我能帮上忙,那真的会很有帮助;因为我真的不知道如何才能做到这一点;我刚刚看过awk,它似乎是完成这项工作的正确工具(我可以为任务编写一个shell脚本),但是如果您认为有更好的方法在shell脚本中完成它,我洗耳恭听:)

提前感谢您的帮助

更新:感谢您的脚本;我得到了Dennis的一个,但是如果每个块中有多个错误条目,它会多次打印同一个块;而bellisarius的示例不返回任何行

我已经添加了一个示例,演示了当我引入错误时日志的样子(末尾有一个空行,但如果我将文本放入标记代码中,则无法添加):

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


希望这更清楚,再次感谢

下次,显示一些示例输入

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
试试这个

awk '/ProcessName/{a = $0; next} {a = a RS $0} /error:/{print a}' inputfile
每次看到“ProcessName”时,它累加行并重置累加器。当它看到“错误:”时,它会打印累加器的内容。

您可以尝试:

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 with err 
error  
salutti

-------

编辑

对于您关于有时在错误记录之前有空记录的评论,您可以通过使用以下awk脚本预处理日志文件来解决此问题,该脚本删除错误消息之前的空行:

/^$/ {getline; if($0 !~ /error/) print ""}  
{print}  

然后在这个输出上运行主脚本。

对于以空行分隔的文件,我发现Perl最容易:

perl -00 -ne 'print if /^ProcessName/ && /error/' afile

-00
选项是一个神奇的咒语,一次向文件传递一个段落。

它将打印文件中的每一行。我忽略了“最后一行将始终是空行”的规定。如果空行分隔块,则可能有一些块没有“ProcessName”,但带有“error:”。您的解决方案可能会在下一个区块意外捕获“错误:”谢谢Dennis;事实上,当块有多个“error:”行时,它会多次打印出相同的错误,因为块中有多少个“error:”实例。我认为您需要在数组中使用递增索引,而不是使用“in”,否则数组元素将不会按定义的顺序排列。您可以这样做来删除整个数组,而无需对其进行迭代:
split(“,a)
(在
gawk
delete a
)。您将在打印它们之后删除它们。删除它们不会影响它们的打印顺序。但是,在中使用
进行迭代以打印它们并不能保证输出的顺序。From:“此语句访问数组元素的顺序由数组元素在`awk'中的内部排列决定,不能控制或更改。”。。。。。。From:“…将迭代,以未指定的顺序将数组的每个索引分配给变量。”感谢Belisarius;我试过了,但它似乎没有打印任何内容:(我添加了一个错误日志示例,因此您可以确切地看到它的结构……可能是我解释错了。@newbiez找不到您的示例。它在哪里?
/^$/ {getline; if($0 !~ /error/) print ""}  
{print}  
perl -00 -ne 'print if /^ProcessName/ && /error/' afile