Reorganizar o arquivo de texto ao incluir linhas de dados com linha de cabeçalho

4

Eu tenho um arquivo cujo conteúdo é assim:

2009 150  0  0  0     0000
75.316   0.0400390625  0.00007        0.00000 0.8980
76.216   0.0400390625  0.00007        1.00000 0.9046
77.217   0.0400390625  0.00009        2.00000 0.9113
78.341   0.0400390625  0.00010        3.00000 0.9183
2009 150  2  0  0     0000
75.316   0.0400390625  0.00007        0.00000 0.8980
76.216   0.0400390625  0.00007        1.00000 0.9046
77.217   0.0400390625  0.00009        2.00000 0.9113
78.341   0.0400390625  0.00010        3.00000 0.9183
79.616   0.0400390625  0.00013        4.00000 0.9255

Eu gostaria de:

  1. Encontre todas as linhas que começam com a palavra-chave 2009.
  2. Anexe previamente essas linhas a todas as outras até que outra ocorrência de linha que comece com 2009 seja encontrada, e assim por diante até EOF.

Essencialmente, estou procurando uma saída como esta:

2009 150  0  0  0     0000 75.316   0.0400390625  0.00007        0.00000 0.8980
2009 150  0  0  0     0000 76.216   0.0400390625  0.00007        1.00000 0.9046
2009 150  0  0  0     0000 77.217   0.0400390625  0.00009        2.00000 0.9113
2009 150  0  0  0     0000 78.341   0.0400390625  0.00010        3.00000 0.9183
2009 150  2  0  0     0000 75.316   0.0400390625  0.00007        0.00000 0.8980
2009 150  2  0  0     0000 76.216   0.0400390625  0.00007        1.00000 0.9046

.......

Eu tenho coçado a cabeça sobre isso por um bom tempo e não consigo chegar a uma solução. Ajuda seria apreciada. Eu sei como extrair o texto entre palavras-chave usando sinalizadores, mas não tenho certeza se essa é a direção certa.

    
por user65305 15.04.2014 / 16:36

3 respostas

5

Você pode usar awk para isso:

awk '/^2009/{a=$0;next}{print a" "$0} ' file.txt

Isso só irá adicionar um espaço a qualquer linha antes da primeira partida de 2009, você pode definir uma string padrão para preceder assim:

awk 'BEGIN{a="My default prepend string";}/^2009/{a=$0;next}{print a" "$0} ' file.txt
    
por 15.04.2014 / 16:44
4

Eu faria isso em Perl:

perl -lne 'if(/^2009/){$n=$_; next} print "$n $_"' file

ou, mais concisamente

perl -lne '/^2009/ ? ($n=$_) : print "$n $_"' file

A ideia é salvar a linha atual ( $_ em Perl) como $n se começar com 2009 e, se não, imprimir a linha atual junto com o valor atual de $n .

    
por 15.04.2014 / 18:20
4

Usando sed :

sed -n '
  /^2009/ { h }
  /^2009/ !{ G; s/^\(.*\)\n\(.*\)$/ /p }
  ' in_file

Explicação conforme solicitado:

-n - faz com que sed não imprima nada a menos que seja informado.

/^2009/ { h } - quando chegarmos a uma linha que começa com 2009 , coloque-a no buffer de retenção.

/^2009/ !{...} - o padrão dentro do {...} é aplicado a todas as linhas que não começam com 2009 .

G; s/^\(.*\)\n\(.*\)$/ /p - G copia o buffer de armazenamento e o acrescenta à linha que acabou de ser lida no espaço padrão. Agora existem duas linhas no espaço de padrão que precisamos trocar a ordem e combinar antes de imprimir. O padrão de substituição com referências anteriores faz exatamente isso.

    
por 15.04.2014 / 16:56