使用sed忽略注释(#),但保持线条不变

时间:2011-01-25 19:52:41

标签: regex shell sed

我有一个配置文件,我想基本上编辑未注释的行,但不是注释行。我正在使用sed

例如,我有一个名为file.txt的文件:

test
# test
# test
test

我想用“TEST”替换“test”但不要触及注释行。最终输出应显示:

TEST
# test
# test
TEST

5 个答案:

答案 0 :(得分:20)

sed '/^#/!s/test/TEST/g' /path/to/infile

输出

$ sed '/^#/!s/test/TEST/g' infile
TEST
# test
# test
TEST

*注意:如果您对评论的唯一要求是第一个非空白字符是#,那么您可以使用:

sed '/^[[:space:]]*#/!s/test/TEST/g' /path/to/infile

输出

$ sed '/^[[:space:]]*#/!s/test/TEST/g' infile
TEST
# test
 # test
TEST

答案 1 :(得分:2)

我不是sed专家,但匹配这些行的正则表达式会看起来像这样的

^[^#].*test

  • ^ - 行首
  • [^#] - 第一个字符,除了#
  • 之外的任何内容
  • .* - 更多字符,未定义
  • test - 您正在寻找的字符串

答案 2 :(得分:1)

要在执行替换时忽略以#开头的注释,您可以使用以下命令:

sed -r 'h;s/[^#]*//1;x;s/#.*//;(substitution command);G;s/(.*)\n/\1/' file.txt

在你的情况下,它变为:

sed -r 'h;s/[^#]*//1;x;s/#.*//;s/test/TEST/g;G;s/(.*)\n/\1/' file.txt

此解决方案优于其他解决方案的优势在于,如果稍后在一行中开始发表评论,它也会起作用,如下面的示例所示。 由于此解决方案使用sed的保持缓冲区,因此如果您需要使用保持缓冲区来执行其他操作,则无法使用此解决方案。

输入

test
# test
test # test
test

输出

TEST
# test
TEST # test
TEST

解释

  1. h; - 保存在保留缓冲区
  2. s/[^#]*//1; - 删除#
  3. 之前的所有内容
  4. x; - 使用保留缓冲区交换
  5. s/#.*//; - 删除评论
  6. s/test/TEST/g; - 将test的所有出现替换为TEST
  7. G; - 附加换行符+保留缓冲区(注释)
  8. s/(.*)\n/\1/ - 删除最后一个换行符
  9. 使用-r时需要\1开关。

答案 3 :(得分:0)

AWK:

awk '!/^[[:space:]]*#/ {gsub(/test/,"TEST")} 1' file.txt

答案 4 :(得分:0)

如果你有Ruby(1.9 +)

ruby -ne 'print $_ !~ /^\s*#/ ?gsub("test","TEST"):$_' file