Usando sed para substituir o multiline

0

Estou tentando substituir a seguinte seção de um arquivo YAML:

  ssl:
    enabled: false

para ler

  ssl:
    enabled: true

Eu tentei isso, que falhou: sed -i s/ssl:\n enabled: false/ssl:\n enabled: true/g

    
por Or Weinberger 21.03.2018 / 10:55

4 respostas

2

Você pode usar sed ranges:

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

Os limites do intervalo são /^ *ssl:/ (início da seção ssl) e /^ *[^:]*:/ (qualquer outra seção).

O s é o comando de substituição usual.

    
por 21.03.2018 / 11:03
2

Use uma ferramenta com reconhecimento de YAML. Por exemplo, em Perl, você pode

perl -MYAML=LoadFile,DumpFile -we '
    $y = LoadFile("file");
    $y->{ssl}{enabled} = "true" if $y->{ssl}{enabled} eq "false";
    DumpFile("file.new", $y);'
    
por 21.03.2018 / 11:18
0

Você estava perto de encontrar e só precisava adicionar a opção -z , e também pode resumir como seguir.

sed -Ez 's/(ssl:\n\s*enabled: )false/true/g' infile
    
por 21.03.2018 / 11:29
0

Desculpe, mas vou concordar com @choroba e pedir que você use uma ferramenta capaz de analisar e escrever yaml. Sed parsing não é o caminho certo. você pode ter recuo diferente, várias linhas finais contínuas. O regexp ficaria muito complicado e você acabaria escrevendo seu próprio analisador Yaml.

Aqui está uma solução em rubi Que você pode usar no shell Bash

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

se você quiser um script de shell que leve dois parâmetros, também é fácil

#!/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)}
    
por 21.03.2018 / 11:48

Tags