Solicite a saída usando sed [duplicate]

0

Eu tenho esta saída depois de executar diff :

< #R1#Number = Gauge32: 258     Name = STRING: "TATA"
---
> #R1#Number = Gauge32: 280     Name = STRING: "TATA"

Eu preciso implementar um comando sed em um script shell para ter esta saída:

Hostname=R1; old=258 new=280, Name="TATA"
    
por toto 05.05.2015 / 11:26

2 respostas

0

Você também pode tentar o Perl:

diff file1 file2 | 
    perl -lne 'if(/^(.).*?#(.+?)#.*?:\s*(\d+).*(".+?")/){
        $1 eq ">" ? print "Hostname=$2; old=$o new=$3, Name=$4" : ( $o=$3 )}'

Explicação

  • O -l adiciona uma nova linha a cada print e o -n fará com que o script fornecido com -e seja aplicado a cada linha do arquivo de entrada.
  • A expressão regular identificará o primeiro caractere ( ^. ), a primeira cadeia entre # ( #(.+?)# ), : seguido por 0 ou mais espaço em branco e um conjunto de números ( :\s*(\d+) ) e a última string citada na linha ( .*(".+?") ). Os parênteses fazem com que estes sejam salvos como $1 a $4 .
  • foo ? bar : baz : esta é uma construção C presente em muitos idiomas. É a abreviação de "se foo é verdade, então faça bar, senão faça baz". Então, se $1 , o primeiro caractere da linha que foi salvo pela operação de correspondência anterior, for > , então imprimiremos e, se não for, salvaremos o terceiro padrão correspondente como $o .

Ou

diff file1 file2 | 
    perl -lane '$o = $F[4] if /^</; $F[1]=~s/#(.*)#.*/$1/; 
        print "Hostname=$F[1]; old=$o new=$F[4], Name=$F[8]" if />/'

Explicação

  • O -a fará o Perl dividir automaticamente cada linha de entrada no espaço em branco e salvá-la no array @F .
  • $o = $F[4] if /^</; : isso salva o quinto campo como $o se o primeiro caractere da linha for < .
  • $F[1]=~s/#(.*)#.*/$1/; : isso removerá tudo, exceto o nome do host do segundo campo ( $F[1] , matrizes são numeradas de 0).
por 05.05.2015 / 13:17
1

Tente isto:

diff ... | sed -n -e '
    /^< / h
    /^---/ H
    /^> / { H; x; s/\n//g;
            s/^< #\([^#][^#]*\)#Number = Gauge32: \([0-9][0-9]*\) .* ##Number = Gauge32: \([0-9][0-9]*\) .* Name = STRING: \("[^"]*"\).*/Hostname=; old= new=, Name=/;
            p; }'

A ideia é colocar tudo em uma única linha e depois pegar apenas as coisas interessantes.

Em detalhes:

  • sed -n - não imprime nada por padrão
  • /^< / h - copia as linhas que começam com < para o espaço de espera
  • /^---/ H - acrescente linhas começando com --- ao espaço de espera
  • /^> / { ... } - para linhas que começam com > , faça o seguinte:
  • H - acrescenta a linha ao espaço de espera
  • x - troca o espaço de espera e o espaço de padrões
  • s/\n//g - remove novas linhas; Neste ponto, o espaço padrão contém algo assim: < #R1#Number = Gauge32: 258 Name = STRING: "TATA"---> #R1#Number = Gauge32: 280 Name = STRING: "TATA"
  • s/.../.../ - formata a saída (nada inteligente aqui, simplesmente sed -fu)
  • p - imprimir

Isso não funciona para diff output geral, onde as alterações podem acontecer em linhas adjacentes. Mas responde à pergunta do jeito que você perguntou.

    
por 05.05.2015 / 12:04