Como adicionar um cabeçalho à saída de um comando awk depois?

0

Eu crio um arquivo (saída) de outro arquivo (entrada) usando o awk (pulando o cabeçalho):

awk 'NR==1{next} $3==1 {print $1"\t"$2}' input > output

Eu então tenho informações de cabeçalho que só posso calcular depois, que adiciono usando sed:

sed -i "1s/^/head1\thead2\n/" output

No entanto, o sed é muito lento, estou querendo saber se existe uma maneira melhor de fazer isso? Como salvar o resultado do awk e depois gravar o arquivo depois de ter as informações do cabeçalho?

    
por Luce 31.05.2017 / 16:52

5 respostas

0

Depois de mais googling, encontrei esta pergunta: Altere o cabeçalho em um arquivo enorme sem reescrevendo o arquivo inteiro .

Para evitar ter que reescrever o arquivo inteiro ao adicionar no cabeçalho, imprimi um cabeçalho fictício de uma quantidade mínima de bytes (preenchendo com zeros) ao criar o arquivo:

awk 'NR==1{print "dummyhead100\tdummyhead20000"; next} $3==1 {print 
$1"\t"$2}' input > output

Eu então faço um arquivo (ou variável string) com o novo cabeçalho como header.tsv, e substituo o cabeçalho fictício no local (depois de ter certeza que os cabeçalhos fictícios e novos são o mesmo número de bytes) usando dd :

dd conv=notrunc obs=1 if=header.tsv of=output

Dessa forma, output é editado no local e não preciso esperar que o arquivo inteiro seja copiado ou tenha que mantê-lo na memória.

    
por 07.06.2017 / 16:54
1

Se você tiver o corpo no arquivo output e o cabeçalho desejado em um arquivo chamado header ( printf "head1\thead2\n" > header ), você poderá inserir o cabeçalho com:

ed -s output <<< $'0r header\nw\nq'

O -s diz para Suprimir a saída de diagnóstico (qual seria quantos bytes ele lia de output , quantos bytes lidos de header e quantos bytes foram gravados no final) .

Os comandos ed são:

  • 0r header - na linha zero, leia o conteúdo do arquivo header
  • w - escreve o arquivo
  • q - quit ed
por 31.05.2017 / 18:11
0

Tente com bash :

echo -e "head1\thead2\n$(cat output)" > /tmp/out && mv /tmp/out output
    
por 31.05.2017 / 16:54
0

Eu faria no bash

{ echo -e "head1\thead2" ; cat output ; } > newoutput

comparado com a resposta de RomanPerekhrest ele funcionará corretamente mesmo para arquivos muito longos (ele carregaria o arquivo primeiro na memória e então executaria o eco; também o bash teria um comprimento máximo de entrada)

    
por 31.05.2017 / 18:44
0

Parece um pouco estranho, mas parece que funciona nos meus testes. Você pode fazer um teste.

echo -e "$head1\t$head2\n" "$(<file5)" >file5

Teste:

$ cat file5
home
help
$ echo -e "header1\theader2\n" "$(<file5)" >file5
$ cat file5
header1 header2
home
help
    
por 01.06.2017 / 23:55