除了匹配范围结束模式的那个之外,如何使用sed打印一系列行?

时间:2011-04-28 15:44:37

标签: regex linux shell sed range

我想知道是否有sed - 唯一的方法来打印一系列线条,这些线条由要匹配的模式决定,除了与最终模式匹配的最后一条线。

考虑以下示例。我有一个文件

line  1
line  2
line  3
ABC line  4
+ line  5
+ line  6
+ line  7
line  8
line  9
line 10
line 11
line 12

我希望以ABC(包括)开头的所有内容以及以+开头的所有行:

ABC line  4
+ line  5
+ line  6
+ line  7

我用

尝试了
sed -n '/ABC/I,/^[^+]/ p' file

但这给了一行太多:

ABC line  4
+ line  5
+ line  6
+ line  7
line  8

离开最后一行的最简单方法是什么(仅限sed?)

4 个答案:

答案 0 :(得分:5)

可能有更好的方法,但我可以拿出这个sed 1班轮:

sed -rn '/ABC/,/^[^+]/{/(ABC|^\+)/!d;p;}' file

另一个sed 1衬垫是

sed -n '/ABC/,/^[^+]/{x;/^$/!p;}' file

另外一个内衬(并且可能更好)

sed -n '/ABC/I{h;:A;$!n;/^+/{H;$!bA};g;p;}' file

答案 1 :(得分:2)

最简单的方法(如果有人能通过一次调用sed来解决这个问题,我会学到一些东西),就是在最后添加一个额外的sed,即

sed -n '/ABC/I,/^[^+]/ p' file | sed '$d'
ABC line  4
+ line  5
+ line  6
+ line  7

作弊,我知道,但这就是Unix管道哲学的美妙之处。继续白化数据,直到得到你想要的东西; - )

我希望这会有所帮助。

答案 2 :(得分:2)

这可能对您有用:

 sed '/^ABC/{:a;n;/^\(ABC\|+\)/ba};d' file

编辑:允许相邻的ABC部分。

答案 3 :(得分:0)

嗯,你选择了答案。但是你为什么不使用/^(ABC|\+)/?或者我误解了你的要求?

如果您想在找到ABC搜索后找到+

awk '/ABC/{f=1;print} f &&/^\+/ { print }' file

这比制作神秘的sed表达式更容易理解。找到ABC时,设置一个标志。当找到以+开头并且设置了标志的行时,打印行。