删除两个方向的n行和sed中的匹配?

时间:2015-05-27 15:44:42

标签: regex bash sed

在比赛前删除比赛和两行:

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: `-'

为什么?

4 个答案:

答案 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这就是我真正做到这一点的工作方式(只需更改ba值,即可在找到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将支持这些构造/选项。