sed 删除以# 开头但不以# 开头的行!(外壳脚本)

use*_*292 4 sed

要删除带有 的行#,以下行可以工作:

sed -i "/^\(\\s\)*\\#/d"
Run Code Online (Sandbox Code Playgroud)

但我想要的是删除##!.

Ale*_*exP 14

sed -i -e '/^\s*#\([^!]\|$\)/d'

在哪里:

  • ^ 行首
  • \s* 零个或多个空白字符
  • # 一个哈希标记
  • \([^!]\|$\)后跟一个不是! 或行尾的字符。


Kus*_*nda 10

sed -i -e '/^#!/p' -e '/^#/d' file
Run Code Online (Sandbox Code Playgroud)

这将逐行遍历文件,当它找到以#!它开头的行时,第一个表达式将打印出来。然后它将被第二个表达式从模式空间中删除(即它不会被默认命令第二次打印,该p命令在不使用时生效sed -n)。

以 just 开头的#行将被第一个表达式忽略,但被第二个表达式删除。

默认p命令将打印任何其他行。

允许前面有空格#(并删除这些行):

sed -i -e '/^[[:blank:]]*#!/p' -e '/^[[:blank:]]*#/d' file
Run Code Online (Sandbox Code Playgroud)

[[:blank:]]表达式将匹配空格或制表符。


由于斯特凡提到的意见,改变pb在第一个表达式将允许sed脚本继续输入的下一行,而不考虑第二个表达式,如果第一个表达式匹配。该b命令分支到预定义的标签,sed如果没有给出标签,则分支到脚本的末尾。这将是一个优化。

  • 参见 `b` 而不是 `p` 到 _branch off_。 (2认同)

Sté*_*las 6

“和”两个地址,您需要一个命令组 ( {...;}):

sed '/^[[:space:]]*#/{/^#!/!d;}' < file
Run Code Online (Sandbox Code Playgroud)

使用 GNU sed,您可以使用-ifor inplace,替换[[:space:]]\s(假设是最新版本)并省略;

sed -i '/^\s*#/{/^#!/!d}' file
Run Code Online (Sandbox Code Playgroud)

您可以嵌套多个,但请注意,可移植性,您不能在}. 所以对于A 和 B 而不是 C 而不是 D,那将是:

sed '/A/{/B/{/C/!{/D/!d;}' -e '}' -e '}' < file
Run Code Online (Sandbox Code Playgroud)

或者:

sed '
  /A/{
    /B/{
      /C/!{
        /D/!d
      }
    }
  }' < file
Run Code Online (Sandbox Code Playgroud)