grep 3 最近发生的事件和发生的一些行

grep 3 latest occurences and some lines around the occurence

我有一个这样的文件:

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

我想 grep 最近两次出现的 exception 关键字及其前 3 行和后 3 行。

我正在使用类似

的东西
grep -C 3 exception | tail -12

我在这里使用 tail -12,因为我希望每次出现 6 行,最近出现 2 行。当出现的异常彼此相距很远时,这很好用,但如果说两次出现都是连续的,则给我无用的行。

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)。我不知道如何让它表现得不一样。

下面的脚本(写在命令行上)读取整个文件并形成一个行数组。然后它遍历它并为每个匹配项打印周围的两行,或者最多 start/end 个数组。

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 选项使它 slurp 整个文件到 $_ 变量中,换行符是 split。迭代遍历数组索引($#m@m 的最后一个元素的索引)。 $bi$ei 是要打印的 begin/end 索引,在数组的开头和结尾附近不能是 +/- 2。

输出可以通过管道传输到 tail,但这不能自动进行:如果匹配在最后两行内,则输出行将减少(一两行),因此需要输入以精确切断而闻名。或者在脚本中找到匹配索引,@idx = grep { $m[$_] =~ /exception/} for 0..$#m;,并在条件中使用它来只打印最后两个。

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

维护逐行处理会使工作复杂得多。我们需要跟踪匹配项,以便我们可以在阅读后打印以下行。但是这里我们需要 多个 这样的记录——对于下一个匹配项,如果它们出现在要打印的以下行中。

这是一个开始:

$ 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] = [=10=]
}

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 行的输入行缓冲区,并且在任何地方找到 "exception" 设置一个指示器,指示 2 行后缓冲区应该被打印,从而打印 "exception" 行加上前后两行。你只需要按摩它来处理 "exception" 发生在输入文件开头或结尾不到 2 行的情况,但是你想要处理它(看看上面的最后一个输出块是如何环绕的,大概是不受欢迎的缓冲区,因为它 运行 离开输入文件的末尾)。