【发布时间】:2011-06-15 10:49:28
【问题描述】:
我有一个配置文件,我想基本上编辑未注释的行,而不是注释的行。我正在使用sed。
例如,我有一个名为 file.txt 的文件:
测试 # 测试 # 测试 测试
我想将“test”替换为“TEST”,但不要触摸注释行。最终输出应显示:
测试 # 测试 # 测试 测试
【问题讨论】:
我有一个配置文件,我想基本上编辑未注释的行,而不是注释的行。我正在使用sed。
例如,我有一个名为 file.txt 的文件:
测试 # 测试 # 测试 测试
我想将“test”替换为“TEST”,但不要触摸注释行。最终输出应显示:
测试 # 测试 # 测试 测试
【问题讨论】:
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
【讨论】:
我不是sed 专家,但匹配这些行的正则表达式看起来像这样某些东西:
^[^#].*test
^ - 行首[^#] - 第一个字符,除了 # 之外的任何字符.* - 更多字符,未定义 test - 你要找的字符串【讨论】:
要在进行替换时忽略以# 开头的 cmets,可以使用以下命令:
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
h; - 保存在保持缓冲区中s/[^#]*//1; - 删除 # 之前的所有内容
x; - 与保持缓冲区交换s/#.*//; - 删除评论s/test/TEST/g; - 将所有出现的test 替换为TEST
G; - 添加换行符 + 保留缓冲区(注释)s/(.*)\n/\1/ - 删除最后一个换行符-r 开关是使用\1 所必需的。
【讨论】:
awk:
awk '!/^[[:space:]]*#/ {gsub(/test/,"TEST")} 1' file.txt
【讨论】:
如果你有 Ruby(1.9+)
ruby -ne 'print $_ !~ /^\s*#/ ?gsub("test","TEST"):$_' file
【讨论】: