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

时间:2014-07-22 13:54:05

标签: 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

注释掉让我们说包含

的行
2001

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

sed -i '/ 2001 /s/^/#/' file

但现在我该怎么回复?

同样取消注释同一行?

我试过

sed -i '/ 2001 /s/^//' file

不起作用。

5 个答案:

答案 0 :(得分:68)

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

sed -i '/<pattern>/s/^/#/g' file

并取消注释:

sed -i '/<pattern>/s/^#//g' file

在你的情况下:

sed -i '/2001/s/^/#/g' file    (to comment out)
sed -i '/2001/s/^#//g' file    (to uncomment)

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

答案 1 :(得分:42)

试试这个sed命令,

sed -i '/^#.* 2001 /s/^#//' file

答案 2 :(得分:5)

使用更通用的 POSIX兼容解决方案来补充@Avinash Raj's helpful answer

  • 切换符合可指定字符串的行,必须在作为单独的字线。
  • 评论字符(字符串)也可指定

请注意解决方案是基于awk,因为由于POSIX&的限制,使用sed的强大便携式解决方案几乎是不可能的#39; 基本正则表达式。

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
  • (^|[[:punct:][:space:]])($|[[:punct:][:space:]])是其他正则表达方言中已知的\<\>字边界断言的POSIX扩展正则表达式等价物。
  • 之后空白保留注释字符,但不在它之前。
  • 当将注释char添加到一行时,它会直接添加前缀,而不是空格。
  • 因此,如果您只使用解决方案切换注释,则会保留所有空格。
  • POSIX awk不提供就地更新(偶然​​也不提供POSIX sed),因此输出首先在临时文件中捕获,然后该文件替换原始文件成功。

答案 3 :(得分:0)

对于不支持标准sed参数的Mac,这会删除井号

sed -i "" "/.*#.*d\/docker-php-ext-xdebug\.ini.*/s/^#//g" docker-compose.yml

答案 4 :(得分:0)

有关如何注释和取消注释文件行的快速示例。

示例文件:

umask 027
TMOUT=600

现在让我们备份文件(只是为了笑)并注释掉和取消注释:

# backup file (because we should always do this)
cp /etc/bash.bashrc /etc/bash.bashrc.$(date '+%Y-%m-%d,%H:%M:%S')

# original: TMOUT=600   , result :# TMOUT=600
sed -i '/[^#]/ s/\(^TMOUT=600.*$\)/#\ \1/' /etc/bash.bashrc

# original # TMOUT=600   ,result :TMOUT=600
sed -i '/^#.*TMOUT=600.*$/s/^#\ //' /etc/bash.bashrc