Mover filas de datos a una sola columna manteniendo los encabezados de fila

Mover filas de datos a una sola columna manteniendo los encabezados de fila

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 nextcomando también evita que la línea 1 sea procesada por el siguiente código, que es solo para las otras líneas. ( FSen 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 BEGINbloque hará que printse 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.

información relacionada