
Tengo informes que se generan en el siguiente formato delimitado por tabulaciones:
UNIT TC CC PC TCP FTX FRX
HOUSE 55 65 75 85 95 105
CAR 100 200 300 400 500 600
H2 5 10 15 20 25 30
C2 10 20 30 40 50 60
Necesito cambiarlos al siguiente formato:
HOUSE TC 55
HOUSE CC 65
HOUSE PC 75
HOUSE TCP 85
HOUSE FTX 95
HOUSE FRX 105
CAR TC 100
CAR CC 200
CAR PC 300
CAR TCP 400
CAR FTX 500
CAR FRX 600
Etcétera.
Me gustaría utilizar herramientas estándar como SED AWK BASH pero cualquier sugerencia es bienvenida. El código se insertará en un script BASH que ya estoy usando para analizar y concatenar los datos de antemano. El número de entradas será siempre el mismo, los informes no cambian.
Respuesta1
Intentar:
$ awk 'BEGIN { FS="\t" } NR==1 { split($0,header,"\t") ; next } { for(i=2;i<=NF;i++) print $1,header[i],$i }' data
HOUSE TC 55
HOUSE CC 65
HOUSE PC 75
HOUSE TCP 85
HOUSE FTX 95
HOUSE FRX 105
CAR TC 100
CAR CC 200
CAR PC 300
CAR TCP 400
CAR FTX 500
CAR FRX 600
H2 TC 5
H2 CC 10
H2 PC 15
H2 TCP 20
H2 FTX 25
H2 FRX 30
C2 TC 10
C2 CC 20
C2 PC 30
C2 TCP 40
C2 FTX 50
C2 FRX 60
El oneliner roto en pedazos:
Establezca el carácter de tabulación como separador de campos de los archivos de entrada:
BEGIN { FS="\t" }
Si la primera línea ( NR==1
) la divide en campos y los almacena en una matriz header
. Esto es más corto que copiar todos los campos $1, $2, ... en un bucle for y almacenarlos. El next
comando también evita que la línea 1 sea procesada por el siguiente código, que es solo para las otras líneas. ( FS
en lugar de "\t"
hubiera sido más consecuente...)
NR==1 { split($0,header,"\t") ; next }
Para cada otra línea ( NR!=1
), imprima todos los campos ( $2...$NF
) con el prefijo $1 y el nombre del campo ( header[i]
).
{ for(i=2;i<=NF;i++) print $1,header[i],$i }
La configuración OFS=FS="\t"
en el BEGIN
bloque hará que print
se utilice una pestaña entre los campos. No cambié esto en la respuesta porque también sería necesario reformatear todas las líneas de salida.