有一个包含在文件中定期重复的模式的大文件,我想在出现某些值以及接下来的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 行)
这是一种方法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行匹配PATTERN
,M
是后面的行数。它设置一个计数器,当遇到第N行匹配时,它保存行号。然后打印从当前行NR
到NR
+ 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次\n
ewline 字符。如果检查成功,它x
再次改变,用命令拉入接下来的M行$!N
并p
打印模式空间然后q
uits。
否则,它只会\n
向保留空间添加另一个ewline 字符,然后 ex
变回。
这个解决方案不太方便,因为当M是一个大数字并且需要一些printf
-fu 来构建sed
脚本时它很快变得很麻烦(更不用说模式和保持空间限制了一些sed
s)。