Incrementar valor e trocar as próximas duas linhas

0

Eu tenho um arquivo de texto com uma sequência de linhas repetindo várias vezes. Por exemplo:

param id: 0
value: 2
description: "hello"

param id: 1
value: 3
description: "world"

Eu quero mover a descrição acima do valor e mudar param id para um valor maior, como param id 1 em vez de 0. Eu quero fazer isso usando scripts. Alguém pode me ajudar com os comandos que podem conseguir isso?

    
por sss07 08.04.2016 / 17:26

4 respostas

1

Como já foi sugerido por @MelBursian nos comentários, eu também seria a favor de awk over sed .

awk '
    BEGIN { OFS=FS=": " }
    {
        if ($1 == "param id") {
            $2 += 1;
        }
        if ($1 == "value") {
            val=$0; getline;
            print; print val;
            next;
        }
        print;
    }
' file
    
por 08.04.2016 / 23:33
0

Isso alternará todas as linhas que começam com "value:" com a respectiva linha seguinte:

sed '/^value: /{N;s/^\(.*\)\n\(.*\)$/\n/}'

Expansão:

  • /^value: / { ... } executará os comandos entre chaves (aqui o falso ... ) apenas para as linhas que correspondem à expressão regular "^ value:"
  • N acrescentará a próxima linha ao espaço do padrão. Assim, podemos operar em duas linhas unidas por uma nova linha a partir de agora.
  • s/^\(.*\)\n\(.*\)$/\n/ mudará o texto antes da nova linha com o texto após a nova linha.
    • s/something/else/ é o comando replace que substituirá "alguma coisa" por "else"
    • ^\(.*\)\n\(.*\)$ corresponderá a qualquer texto desde o início do espaço de padrão até um novo caractere de linha e salvará como expressão 1 e, em seguida, todos os caracteres adicionais no final do espaço de padrão serão salvos como expressão dois
    • \n colocará a expressão dois seguida por uma nova linha e depois a expressão um como substituto
por 08.04.2016 / 17:53
0

Para incrementar um valor com sed é extremamente não recomendado. não é a ferramenta correta para esse trabalho. Mas se tiver que ser sed , isso funciona apenas com o GNU sed .

sed -rn '/^param/{s/(.*)([0-9]+)/echo $((+1))/e;p;n;h;n;p;x;p;n;p}' file
  • -r ativa expressões regulares estendidas.
  • -n desativa a impressão automática de sed .
  • /^param/ procura por uma linha que começa com o padrão param .
    • s/(.*)([0-9]+)/echo $((+1))/e agora faz uma pesquisa / substituição nessa linha. Procure o número ([0-9]+) e substitua-o por echo $((+1)) , que será executado. e in s///e é o modificador que executou o padrão correspondente em um shell.
    • p; imprime a linha alterada.
    • n; carrega a próxima linha no espaço padrão (a linha value ).
    • h; copia essa linha para o espaço de espera.
    • n;p; carrega a próxima linha (a linha description ) e a imprime.
    • x; troca o padrão e o espaço de espera.
    • p; imprime essa linha.
    • n;p carrega a próxima linha (a linha vazia) e a imprime.

A saída com sua entrada de exemplo:

param id: 1
description: "hello"
value: 2

param id: 2
description: "world"
value: 3
    
por 08.04.2016 / 18:21
0

A linha em movimento é mais facilmente feita com POSIX ex ; O incremento numérico é mais facilmente feito com awk . Felizmente, ex permite filtrar linhas específicas por meio de ferramentas externas:

printf %s\n 'g/description/m-2' 'g/param id/.!awk "++\$NF"' x | ex file

Traduzido para o inglês, o primeiro comando é "Mover todas as linhas que contenham a palavra 'descrição' uma linha."

(Há um 2 lá porque, mais literalmente traduzido, é "Mova essas linhas para o ponto logo após as linhas de duas linhas para cima.")

O segundo é: "Filtre cada linha que contém 'param id' até awk ."

O comando awk é "Incrementar o campo final da linha (e imprimir a linha, a menos que o resultado seja zero. :)"

x é "Salvar e sair".

    
por 09.04.2016 / 01:58