如何使用Sed取消包含特定字符串的行?

44 bash awk sed

文件中的行:

-A INPUT -m state --state NEW -m tcp -p tcp --dport 2000 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 2001 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 2002 -j ACCEPT
Run Code Online (Sandbox Code Playgroud)

注释掉让我们说包含的行

2001
Run Code Online (Sandbox Code Playgroud)

我可以简单地运行这个SED命令:

sed -i '/ 2001 /s/^/#/' file
Run Code Online (Sandbox Code Playgroud)

但现在我该怎么回复?

在取消注释同一行?

我试过了

sed -i '/ 2001 /s/^//' file
Run Code Online (Sandbox Code Playgroud)

这不起作用.

JNL*_*NLK 78

是的,要用sed评论包含特定字符串的行,只需执行以下操作:

sed -i '/<pattern>/s/^/#/g' file
Run Code Online (Sandbox Code Playgroud)

并取消注释:

sed -i '/<pattern>/s/^#//g' file
Run Code Online (Sandbox Code Playgroud)

在你的情况下:

sed -i '/2001/s/^/#/g' file    (to comment out)
sed -i '/2001/s/^#//g' file    (to uncomment)
Run Code Online (Sandbox Code Playgroud)

最后的选项"g"意味着全球变化.如果您只想更改单个模式实例,请跳过此步骤.

  • 为避免多次注释并考虑多个前导`#`,请使用以下命令:`sed -i'/ <pattern>/s/^#*/#/ g'文件(注释掉)`和`sed -i'/ <pattern>/s/^#*// g'文件(取消注释)` (6认同)
  • 如果你想确保行首没有空格(例如在`#This is commented out`中,你可以使用`sed -i '/&lt;pattern&gt;/s/^#*\s*//g '文件` (5认同)

Avi*_*Raj 47

试试这个sed命令,

sed -i '/^#.* 2001 /s/^#//' file
Run Code Online (Sandbox Code Playgroud)

  • 为什么`.`会删除第一个字符,即使它不是评论? (2认同)
  • 仍然需要证明失败.如果要选择,这个答案需要更正 (2认同)

mkl*_*nt0 6

为了补充@Avinash Raj的有用的答案有一个更通用的,POSIX兼容的解决方案.

  • 切换可指定字符串匹配的行的注释,字符串必须作为行中任意位置的单独单词出现.
  • 注释字符(串),也可指定.

请注意,该解决方案是awk基于的,因为由于POSIX的基本正则表达式的限制,几乎不可能实现强大的可移植解决方案.sed

awk -v commentId='#' -v word='2001' '
  $0 ~ "(^|[[:punct:][:space:]])" word "($|[[:punct:][:space:]])" { 
    if (match($0, "^[[:space:]]*" commentId))
      $0 = substr($0, RSTART + RLENGTH)
    else
      $0 = commentId $0
  } 
  { print }
  ' file > tmpfile.$$ && mv tmpfile.$$ file
Run Code Online (Sandbox Code Playgroud)
  • (^|[[:punct:][:space:]])并且($|[[:punct:][:space:]])是从其他正则表达式方言中已知的POSIX扩展正则表达式\<\>字边界断言.
  • 保留注释char 的空格,但不保留它.
  • 在将注释char添加到一行时,它是直接前置的,没有空格.
  • 因此,如果您只使用解决方案切换注释,则会保留所有空格.
  • POSIX awk不提供就地更新(偶尔也不提供POSIX sed),因此输出首先在临时文件中捕获,然后该文件在成功时替换原始文件.