提取第 n 行匹配模式和接下来的 N 行

Moh*_*awy 3 text-processing

有一个包含在文件中定期重复的模式的大文件,我想在出现某些值以及接下来的N行后仅提取特定模式。
这是一个例子,但之前的数字members of the group并不真正存在。

输入:

1 members of the group
...
...
2 members of the group
...
...
...
n members of the group
...
...
...
Run Code Online (Sandbox Code Playgroud)

输出:

85 members of the group
...
...
...
...
...
Run Code Online (Sandbox Code Playgroud)

(第 85 场比赛和接下来的 5 行)

don*_*sti 6

这是一种方法awk

awk -vN=85 -vM=5 'BEGIN{c=0}
/PATTERN/{c++
{if (c==N) {l=NR;last=NR+M}}
}{if (NR<=last && NR>=l) print}' infile
Run Code Online (Sandbox Code Playgroud)

哪里N是第N行匹配PATTERNM是后面的行数。它设置一个计数器,当遇到第N行匹配时,它保存行号。然后打印从当前行NRNR+ M 的行


作为记录,这就是您使用sed(gnu sed语法) 的方式:

sed -nE '/PATTERN/{x;/\n{84}/{x;$!N;$!N;$!N;$!N;$!N;p;q};s/.*/&\n/;x}' infile
Run Code Online (Sandbox Code Playgroud)

这是使用保持空间进行计数。
每次遇到与其匹配的行时,PATTERN都会x更改缓冲区并检查保持缓冲区中是否出现了N-1\newline 字符。如果检查成功,它x再次改变,用命令拉入接下来的M$!Np打印模式空间然后quits。
否则,它只会\n向保留空间添加另一个ewline 字符,然后 ex变回。
这个解决方案不太方便,因为当M是一个大数字并且需要一些printf-fu 来构建sed脚本时它很快变得很麻烦(更不用说模式和保持空间限制了一些seds)。