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

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

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

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

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

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

Porém, o sed é bem lento, gostaria de saber se existe uma maneira melhor de fazer isso? Como salvar o resultado do awk e depois gravar o arquivo depois de obter as informações do cabeçalho?

Responder1

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

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

O -stexto diz para suprimir a saída de diagnóstico (que seria quantos bytes ele leu from output, quantos bytes ele leu from headere quantos bytes ele gravou no final).

Os comandos ed são:

  • 0r header- na linha zero, leia o conteúdo do arquivoheader
  • w- escreva o arquivo
  • q- desisti

Responder2

Experimente comfesta:

echo -e "head1\thead2\n$(cat output)" > /tmp/out && mv /tmp/out output

Responder3

eu faria no bash

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

comparado à resposta de RomanPerekhrest, ele funcionará corretamente mesmo para arquivos muito longos (ele carregaria o arquivo primeiro na memória e depois executaria o eco; também o bash possui algum comprimento máximo de entrada)

Responder4

Depois de pesquisar mais no Google, encontrei esta pergunta: Altere o cabeçalho de um arquivo enorme sem reescrever o arquivo inteiro.

Para evitar ter que reescrever o arquivo inteiro ao adicionar o cabeçalho, imprimi um cabeçalho fictício com 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

Em seguida, crio um arquivo (ou variável de string) com o novo cabeçalho como header.tsv e substituo o cabeçalho fictício no local (depois de garantir que o cabeçalho fictício e o novo tenham o mesmo número de bytes) usando dd:

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

Dessa forma output, a edição é feita no local e não preciso esperar que o arquivo inteiro seja copiado, nem preciso mantê-lo na memória.

informação relacionada