perl - grep 3 最新出现的内容以及该出现周围的一些行

标签 perl unix grep tail

我有一个文件,例如:

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

我想 grep 最近 2 次出现的异常关键字及其前 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)。我不知道如何让它表现出其他行为。

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

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 是要打印的开始/结束索引,在数组的开头和结尾附近不能为 +/- 2。

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

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

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

关于perl - grep 3 最新出现的内容以及该出现周围的一些行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44491833/

相关文章:

linux - 为什么 perl 调试器找不到脚本找到的模块?

perl - 如何在 Perl 中解析符号链接(symbolic link)?

perl - 使用 perl 进行 DNA 分析的基本正则表达式和字符串操作

python - 无法连接到python中的抽象unix套接字

sql - 在 Perl 中的 PostgreSQL 中参数化时间戳引用的问题

linux - regex() 和 regcmp() 函数不在 LINUX 中

linux - Unix - 通过匹配前 91 个字符来获取文件 2 中不在文件 1 中的记录

linux - 使用 grep 查找两个 's' 由空格分隔的单词

regex - 使用 grep 在多个文件中查找字符串

bash - 如何在现有txt文件中添加新行