¿Cómo agregar un encabezado a la salida de un comando awk posteriormente?

¿Cómo agregar un encabezado a la salida de un comando awk posteriormente?

Creo un archivo (salida) a partir de otro archivo (entrada) usando awk (omitiendo el encabezado):

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

Luego tengo información de encabezado que solo puedo calcular después, que agrego usando sed:

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

Sin embargo, el sed es bastante lento. Me pregunto si hay una mejor manera de hacerlo. ¿Te gusta guardar el resultado de awk y luego escribir el archivo después de tener la información del encabezado?

Respuesta1

Si tiene el cuerpo del outputarchivo y el encabezado deseado en un archivo llamado header( printf "head1\thead2\n" > header), puede insertar el encabezado con:

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

Dice -sSuprimir la salida de diagnóstico (que sería cuántos bytes leyó output, cuántos bytes leyó headery cuántos bytes escribió al final).

Los comandos ed son:

  • 0r header- en la línea cero, lea el contenido del archivoheader
  • w- escribe el archivo
  • q- dejar de fumar

Respuesta2

Pruebe conintento:

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

Respuesta3

lo haría en bash

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

en comparación con la respuesta de RomanPerekhrest, funcionará correctamente incluso para archivos muy largos (el suyo cargaría el archivo primero en la memoria y luego ejecutaría el eco; también bash tiene, en mi humilde opinión, una longitud máxima de entrada)

Respuesta4

Después de buscar más en Google, encontré esta pregunta: Cambie el encabezado de un archivo enorme sin reescribir todo el archivo.

Para evitar tener que reescribir todo el archivo al agregar el encabezado, imprimí un encabezado ficticio de una cantidad mínima de bytes (rellenando con ceros) mientras creaba el archivo:

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

Luego creo un archivo (o variable de cadena) con el nuevo encabezado como header.tsv, y reemplazo el encabezado ficticio en su lugar (después de asegurarme de que los encabezados ficticios y nuevos tengan el mismo número de bytes) usando dd:

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

De esta manera outputse edita en el lugar y no tengo que esperar a que se copie todo el archivo ni tener que guardarlo en la memoria.

información relacionada