如何打印10行以上,直到每个匹配行下面的匹配单词?

时间:2017-10-29 22:00:01

标签: parsing sed terminal grep

我需要解析日志文件,以便输出错误(下面是堆栈跟踪),每个错误上面10行。

例如:

2017-10-29 00:00:10,440 INFO ...
2017-10-29 00:00:10,473警告......
2017-10-29 00:00:10,504 INFO ...
2017-10-29 00:00:10,547 INFO ...
2017-10-29 00:00:10,610 INFO ...
2017-10-29 00:00:11,176警告......
2017-10-29 00:00:11,894警告..
2017-10-29 00:00:11,900 INFO ...
2017-10-29 00:00:11,900 INFO ...
2017-10-29 00:00:12,632警告...
2017-10-29 00:00:12,946错误...
...(堆栈跟踪)...
...(堆栈跟踪)...
......(堆栈跟踪)......

2017-10-29 00:00:12,946警告

我需要在ERROR上方输出10行,直到下面的日期(2017-10-29)(不包括日期行)

考虑使用grep -n -B10" ERROR"(对于上面的10行)和sed' / ERROR /,/ 29 / p'(对于堆栈跟踪) )但我如何将两者结合起来?

4 个答案:

答案 0 :(得分:1)

使用 grep + head 管道:

grep -B10 'ERROR' g1 | head -n -1

答案 1 :(得分:0)

这可能适合你(GNU sed):

sed -n ':a;N;/ERROR/bb;s/[^\n]\+/&/11;Ta;D;:b;p;n;/2017-10-29$/!bb' file

在模式空间中最多收集10行,然后使用这些行作为文件的移动窗口。遇到字符串ERROR时,打印窗口,然后再匹配任何其他行,直到(但不包括)字符串2017-10-29匹配。必要时重复。

答案 2 :(得分:0)

这是一种使用awk的方法:

awk '                     {a[++b]=$0}
     /^([0-9]{2,4}-?){3}/ {f=0}
     /ERROR/              {f=1; for(i=NR-10;i<NR;i++) print a[i]}
     f' file

我们将每一行存储到数组中。匹配日期日志行时,我们取消设置标志。匹配ERROR时,我们设置标志,然后打印数组的最后10行。当标志打开时,我们打印(默认操作,所以我们只写了f

这应该打印文件中所有现有ERROR的预期行。

注意:使用的日期regexp并不严格,但看起来足够了。

答案 3 :(得分:0)

试试这个

grep -no -B10 ' [0-9:,]* ERROR.*' infile

或许需要替代&#39; &#39;通过[[:blank:]]