我有几个文件一样file1,file2在同一个目录...等等,并且每个文件可以包含多行匹配PATTERN。
我想N从匹配的每一行中删除第th 行,PATTERN例如与N=3和file1内容如
1 no match
2 PATTERN
3 same PATTERN
4 no match here
5 no match here either
6 another PATTERN
7 again, no match
8 no
9 last line
Run Code Online (Sandbox Code Playgroud)
预期的输出是
1 no match
2 PATTERN
3 same PATTERN
4 no match here
7 again, no match
8 no
Run Code Online (Sandbox Code Playgroud)
就地编辑文件是一种奖励,而不是要求(尽管gnu我知道至少有一种工具可以一次性编辑所有文件......)
这里提出了一个类似的问题,但这是一个特殊情况(每个文件中只有一个单行匹配模式,如果它们被至少N + 1 个非匹配行分隔,则那里的解决方案只能使用多行匹配模式)。
你可以使用awk我相信像这样:
awk -vN=3 '/PATTERN/ {skips[FNR+N]=1;} {if(!(FNR in skips)) print;}' <file>
Run Code Online (Sandbox Code Playgroud)
所以每次我们点击时,PATTERN我们都会记录N远离这里的行,并且只打印那些我们没有标记为跳过的行。
使用gawk,您也可以使用-i inplace它来就地进行
正如您所指出的,这不会处理多个文件。当然,你可以用一个for循环来遍历所有文件,但如果没有足够的使命令行太长,你也可以这样做:
awk -vN=3 '{if(FNR==1) split("", skips, ":");} /PATTERN/ {skips[FNR+N]=1;} {if(!(FNR in skips)) print;}' *
Run Code Online (Sandbox Code Playgroud)
我们skips在每次FNR达到 1时重置为一个空数组,因此每个文件的开头。
随着gnu awk你可以写为:
gawk -i inplace 'FNR==1{delete nr};/PATTERN/{nr[FNR+3]++};!(FNR in nr)' file*
Run Code Online (Sandbox Code Playgroud)