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 output
archivo 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 -s
Suprimir la salida de diagnóstico (que sería cuántos bytes leyó output
, cuántos bytes leyó header
y 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 archivoq
- 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 output
se edita en el lugar y no tengo que esperar a que se copie todo el archivo ni tener que guardarlo en la memoria.