我有以以下制表符分隔格式生成的报告:
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"
块中的设置BEGIN
将print
在字段之间使用制表符。我没有在答案中更改这一点,因为它也需要重新格式化所有输出行。