使用 sed 替换多行

使用 sed 替换多行

我正在尝试替换 YAML 文件的以下部分:

  ssl:
    enabled: false

读书

  ssl:
    enabled: true

我尝试过这个,但失败了:sed -i s/ssl:\n enabled: false/ssl:\n enabled: true/g

答案1

您可以使用sed范围:

sed '/^ *ssl:/,/^ *[^:]*:/s/enabled: false/enabled: true/' file

范围边界是/^ *ssl:/(ssl 部分的开头)和/^ *[^:]*:/(任何其他部分)。

s是通常的替换命令。

答案2

使用支持 YAML 的工具。例如,在 Perl 中,您可以

perl -MYAML=LoadFile,DumpFile -we '
    $y = LoadFile("file");
    $y->{ssl}{enabled} = "true" if $y->{ssl}{enabled} eq "false";
    DumpFile("file.new", $y);'

答案3

抱歉,但我会同意@choroba,并告诉你使用能够解析和编写 yaml 的工具。 sed 解析不是正确的方法。你可能有不同的缩进,几个连续的端线。正则表达式会变得过于复杂,您最终会编写自己的 Yaml 解析器。

这是 ruby​​ 中的解决方案,您可以在 Bash shell 中使用

echo "ssl:
enabled: false
" | bundle exec ruby -e "require 'psych';
 c = Psych.load(STDIN.read); c['ssl']['enabled'] = true;
 puts c.to_yaml" > updated_dest.yml

如果你想要一个带有两个参数的 shell 脚本,也很简单

#!/usr/bin/env ruby

require 'psych'
c = Psych.load_file(ARGV.shift)
c['ssl']['enabled'] = true
File.open(ARGV.shift, 'wb+') {|f| f.write(c.to_yaml)}

相关内容