grep 3最新发生和一些线周围的事件

我有一个像这样的文件:

exception: anythinggggg... exception: anythinggggg... abchdhjsdhsd ygsuhesnkc exception: anythingggg... exception: anything... .. .. 

我想grep最近的两次exception关键字,以及之前的3行和之后的3行。

我正在使用类似的东西

 grep -C 3 exception | tail -12 

我在这里使用尾巴-12,因为我想每次出现6行,最近2次出现。 这个工作正常时发生的exception是远离对方,但给我无用的线,如果说这两个事件是连续的。

 abdgjsd abdgjsd abdgjsd abdgjsd abdgjsd abdgjsd abdgjsd abdgjsd exception exception exception abcd 

在上述情况下,它给了我

 abdgjsd abdgjsd abdgjsd exception exception exception abcd 

不过,我想要的是

 abdgjsd exception exception -----------------> OUTPUT FOR FIRST OCCURRENCE exception abcd abdgjsd abdgjsd exception-----------------> OUTPUT FOR SECOND OCCURRENCE exception exception abcd 

有没有另一种方法呢? 也许我也可以指定出现次数,而不仅仅是grep行,并从它尾部输出。

你得到的输出是因为grep停止打印上下文( -C )在下一场比赛。 我不知道如何使其行为。

下面的脚本(写在命令行上)读取整个文件并形成一个行数组。 然后通过它打印每个匹配周围的两行,或者直到数组的开始/结束。

 perl -MList::Util=min,max -0777 -wnE' @m = split /\n/; for (0..$#m) { if ($m[$_] =~ /exception/) { $bi = max(0,$_-2); $ei = min($_+2, $#m); say for @m[$bi..$ei]; say "---" } } ' input.txt 

打印---是为了方便查看输出。 这将打印所需的输出。

-0777选项使得整个文件变成$_变量,这个变量被换行符分隔。 迭代遍历数组索引( $#m@m的最后一个元素的索引)。 $bi$ei是打印的开始/结束索引,在数组的开头和结尾附近不能是+/- 2。

输出可以输送到tail但这不能自动化:如果匹配在最后两行内,则会有(一两个)较少的输出行,因此输入需要知道精确的截止点。 或者在脚本中找到匹配的索引, @idx = grep { $m[$_] =~ /exception/} for 0..$#m; ,并在条件中使用它只打印最后两个。

如果你打算使用这样的东西,我会把它做成一个脚本。 然后将所有行直接读入数组,提供命令行选项(如grep -C )等

保持逐行处理会使工作变得更加复杂。 我们需要跟踪一场比赛,以便我们一读完就可以打印下面的内容。 但是在这里我们需要多个这样的记录 – 对于下一个匹配(es),如果它们在下面的行中被打印。

这是一个开始:

 $ cat tst.awk BEGIN { bufSize = 5 } { updBuf(NR) } /exception/ { rangeEndNrs[NR+int(bufSize/2)] } NR in rangeEndNrs { prtBuf(NR) } END { prtBuf(NR+1) } function updBuf(nr) { buf[((nr-1)%bufSize)+1] = $0 } function prtBuf(nr, i) { for (i=1; i<=bufSize; i++) { print buf[((nr+i-1)%bufSize)+1] } print "---" } 

 $ awk -f tst.awk file abdgjsd abdgjsd exception exception exception --- abdgjsd exception exception exception abcd --- exception exception exception abcd abdgjsd --- 

它的工作原理是只保留一行5行缓冲区的输入行,并且发现每一个“异常”都会设置一个指示符,以便在后面打印两行缓冲区,从而打印“异常”行和前后两行。 你只需要按它来处理从输入文件的开头或结尾出现少于2行的“异常”的情况,但是你想要处理的(看看上面的最后一个输出块大概是不希望的,是如何绕过缓冲区的因为它运行在输入文件的末尾)。