使用sed删除两个匹配模式之间的所有行

我有一个像这样的文件:

# ID 1 blah blah blah blah $ description 1 blah blah # ID 2 blah $ description 2 blah blah blah blah 

如何使用sed命令删除#$行之间的所有行? 所以结果会变成:

 # ID 1 $ description 1 blah blah # ID 2 $ description 2 blah blah blah blah 

你能不能请解释一下?

使用这个sed命令来实现:

 sed '/^#/,/^\$/{/^#/!{/^\$/!d}}' file.txt 

Mac用户(为了防止extra characters at the end of d command错误extra characters at the end of d command )需要在右括号之前添加分号

 sed '/^#/,/^\$/{/^#/!{/^\$/!d;};}' file.txt 

OUTPUT

 # ID 1 $ description 1 blah blah # ID 2 $ description 2 blah blah blah blah 

说明:

  • /^#/,/^\$/将匹配以#开头的行到以$开头的行之间的所有文本。 ^用于开始行字符。 $是一个特殊的字符,所以需要转义。
  • /^#/! 意味着如果开始行不是#
  • /^$/! 意味着如果行的开始不是$则执行以下操作
  • d表示删除

所以总的来说,首先匹配从^#^\$所有行,然后从匹配的行中find不匹配 ^#行,并且不匹配 ^\$并使用d删除它们。

 $ cat test 1 start 2 end 3 $ sed -n '1,/start/p;/end/,$p' test 1 start end 3 $ sed '/start/,/end/d' test 1 3 

我很久以前做过类似这样的事情:

 sed -n -e "1,/# ID 1/ p" -e "/\$ description 1/,$ p" 

这是这样的:

  • -n禁止所有输出
  • -e "1,/# ID 1/ p"从第一行开始执行直到你的模式和p(打印)
  • -e "/\$ description 1/,$ p"从第二个模式执行直到结束并且p(打印)。

我可能是错误的一些逃避的string,所以请仔细检查。

sed的另一个方法:

 sed '/^#/,/^\$/{//!d;};' file 
  • /^#/,/^\$/ :从以#开始的行开始,直到以$开头的下一行
  • //!d :删除除地址模式匹配的所有行

一般情况下,如果你有一个abcdeforms的内容的文件,其中a部分在模式b之前,那么c部分在模式d之前,然后在e之后 ,你应用下面的sed命令,你会得到如下结果。

在这个演示中,输出由=> abcde表示,其中的字母显示哪些部分在输出中。 因此, ae仅显示ae部分的输出, aceace等部分。

请注意,如果bd出现在输出中,那么出现的模式(即它们被视为输出中的部分)。

也不要将/d/ pattern与命令d混淆。 这些示威中的指挥总是在最后。 模式总是在//之间。

sed -n -e '/b/,/d/!p' abcde => ae

sed -n -e '/b/,/d/p' abcde => bcd

sed -n -e '/b/,/d/{//!p}' abcde => c

sed -n -e '/b/,/d/{//p}' abcde => bd

sed -e '/b/,/d/!d' abcde => bcd

sed -e '/b/,/d/d' abcde => ae

sed -e '/b/,/d/{//!d}' abcde => abde

sed -e '/b/,/d/{//d}' abcde => ace