在比赛前删除比赛和两行:
sed -i.bak -e '/match/,-2d' someCommonName.txt
删除匹配项及其后的两行:
sed -i.bak -e '/match/,+2d' someCommonName.txt
但是删除匹配,在它之后的两行和它之前的两行不起作用?
sed -i.bak -e '/match/-2,+2d' someCommonName.txt
sed: -e expression #1 unknown command: `-'
为什么?
答案 0 :(得分:2)
我没有完整的解决方案但是大纲:sed
是一个非常简单的工具,它不会同时做两件事。我的方法是在模式之后删除两行但是保留模式本身时运行sed
。然后可以将结果再次传送到sed
以删除模式和之前的两行。
答案 1 :(得分:2)
sed
对一系列地址进行操作。这意味着一个或两个表达式,而不是三个。
/match/
是一个与正则表达式匹配的地址。
-2
是一个在
+2
是一个地址,用于指定
因此:
/match/,-2
是一个范围,用于指定之前与两行匹配match
的行。
/match/-2,+2d
包括三个地址,因此毫无意义。
要删除模式前后的两行,我建议这样的(modified from this answer):
sed -n "1N;2N;/\npattern$/{N;N;d};P;N;D"
这会在缓冲区中保留3行并读取文件。当在最后一行找到模式时,它会再读取两行并删除所有5.注意,如果模式位于文件的前两行,但这是一个开始,这将不起作用。
答案 2 :(得分:2)
sed -i .bak '/match/,-2 {/match/!d;};/match/,+2d' YourFile
尝试此操作(无法在此测试,我的sed版本中无法使用-2
)
答案 3 :(得分:1)
FWIW这就是我真正做到这一点的工作方式(只需更改b
和a
值,即可在找到match
之前/之后删除不同数量的行:
$ cat file
1
2
3
4
5 match
6
7
8
9
$ awk -v b=2 -v a=2 'NR==FNR{if (/match/) for (i=(NR-b);i<=(NR+a);i++) skip[i]; next } !(FNR in skip)' file file
1
2
8
9
$ awk -v b=3 -v a=1 'NR==FNR{if (/match/) for (i=(NR-b);i<=(NR+a);i++) skip[i]; next } !(FNR in skip)' file file
1
7
8
9
请注意,上面假设当2&#34;匹配&#34; s出现在删除窗口中时,您希望将删除基于原始事件,而不是在找到第一个匹配后会发生什么导致第二个匹配被删除:
$ cat file2
1
2
3
4 match
5
6 match
7
8
9
$ awk -v b=2 -v a=2 'NR==FNR{if (/match/) for (i=(NR-b);i<=(NR+a);i++) skip[i]; next } !(FNR in skip)' file2 file2
1
9
而不是输出:
1
7
8
9
因为删除第一个match
之后的2行将删除第二个match
,因此THAT之后的2行不会被删除,因为它们不再在{{1}之后的2行内}。
需要考虑的其他事项:
match
使用bash和GNU diff 3.2,idk if /其他shell / diffs将支持这些构造/选项。