首页 > 解决方案 > SED:匹配后删除 X 行

问题描述

我正在尝试使用sed. 范围来自已知匹配和接下来的 2 行。假设我想删除所有以开头的行,Don't然后是后面的 2 行。

请注意,我也在 sed 命令文件中进行替换。因此,我避免在我的解决方案空间中 使用-n和。/p

无论出于何种原因,我都想限制自己只调用一次 sed。

这是我的数据(data.txt):

Print Me
Please Output This line
Don't Print Me and 2 more lines
This line is no good
So is this one
We should see this line
And this one, too.

这是我的预期输出:

Print Me
Please Output This line
We should see this line
And this one, too.

这是一个尝试:

sed -f delete_dont_plus_2.sed data.txt

以此为delete_dont_plus_2.sed

/^Don't/,+2d

这是我的结果:

sed: 1: delete_dont_plus_2.sed: expected context address

我也试过这些:

/^Don't/,/^Don't/+2d
/^Don't/,{/^Don't/+2}d

这个问题的第二种方法:

假设我们想让这段代码更健壮一些。今天还有2行需要删除,但谁知道将来会有多少行。假设我们要删除最多但不包括We should see this line. 在这个问题的变体中,结果完全相同。同样,让我们​​考虑一个有限的 BSD sed,因此我们不能使用像/^Don't/,/^We should see this line/-1d.

谢谢!

标签: macossed

解决方案


您可能正在使用不支持regexp,+n格式地址的 sed。以下是针对这种特殊情况的解决方法:

/^Don't/{N;N;d;}

它只是在找到时将另外两行读入模式空间^Don't并将它们完全删除。

但无论如何,我认为 sed 不是正确的工具,你应该使用代替。例如:

awk '/^Don\047t/{c=2;next} !(c&&c--)' file

cf:使用 sed 或 awk 打印匹配模式后的一行


假设我们要删除最多但不包括We should see this line. 在这个问题的变体中,结果完全相同。

使用 sed 您需要编写相同的 RE 两次:

/^Don't/,/^We should see this line/{/^We should see this line/!d;}

使用 awk 你甚至不需要 RE:

awk 'index($0,"Don\047t")==1{d=1} $0=="We should see this line"{d=0} !d' file

推荐阅读