将数据行移动到单列,同时保留行标题

将数据行移动到单列,同时保留行标题

我有以以下制表符分隔格式生成的报告:

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

我需要将它们更改为以下格式:

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

等等。

我想使用标准工具,例如 SED AWK BASH,但欢迎任何建议。该代码将被插入到一个 BASH 脚本中,我已经使用该脚本预先解析和连接数据。因此条目的数量将始终相同,报告不会改变。

答案1

尝试:

$ 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

内衬碎成碎片:

将制表符设置为输入文件的字段分隔符:

BEGIN { FS="\t" }

如果第一行 ( NR==1) 将其拆分为字段并将它们存储在数组中header。这个简单比在 for 循环中复制所有字段 $1, $2, ... 并存储它们要短。该next命令也阻止第 1 行被以下代码处理,这仅适用于其他行。 (FS而不是"\t"会产生更严重的后果......)

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

对于其他每一行 ( NR!=1),打印$2...$NF以 $1 为前缀的所有字段 ( ) 和字段名称 ( header[i])。

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

OFS=FS="\t"块中的设置BEGINprint在字段之间使用制表符。我没有在答案中更改这一点,因为它也需要重新格式化所有输出行。

相关内容