Mover linha (s) de dados para coluna única enquanto retém cabeçalho (s) de linha

1

Tenho relatórios gerados no seguinte formato delimitado por tabulações:

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

Eu preciso alterá-los para o seguinte 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

E assim por diante.

Eu gostaria de usar ferramentas padrão, como o SED AWK BASH, mas qualquer sugestão é bem-vinda. O código será inserido em um script BASH que eu já estou usando para analisar e concatenar os dados de antemão. O número para que as entradas sejam sempre as mesmas, os relatórios não mudam.

    
por user72055 12.06.2014 / 14:24

1 resposta

1

Tente:

$ 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

O oneliner quebrado em pedaços:

Definir o atributo tab como separador de campo dos arquivos de entrada:

BEGIN { FS="\t" }

Se a primeira linha ( NR==1 ) dividir em campos e armazená-los na matriz header . Este simpy é mais curto do que copiar todos os campos $ 1, $ 2, ... em um loop e armazená-los. O comando next impede que a linha 1 seja processada pelo código a seguir também, que é apenas para as outras linhas. ( FS em vez de "\t" teria sido mais consequente ...)

NR==1 { split($0,header,"\t") ; next }

Para cada outra linha ( NR!=1 ) imprima todos os campos ( $2...$NF ) prefixados por $ 1 e o nome do campo ( header[i] ).

{ for(i=2;i<=NF;i++) print $1,header[i],$i }

A definição de OFS=FS="\t" no bloco BEGIN fará com que print use uma guia entre os campos. Eu não mudei isso na resposta porque seria necessário reformatar todas as linhas de saída também.

    
por 12.06.2014 / 14:38