![使用 awk 基于行值动态将行转置为列](https://linux22.com/image/127872/%E4%BD%BF%E7%94%A8%20awk%20%E5%9F%BA%E4%BA%8E%E8%A1%8C%E5%80%BC%E5%8A%A8%E6%80%81%E5%B0%86%E8%A1%8C%E8%BD%AC%E7%BD%AE%E4%B8%BA%E5%88%97.png)
我的文件包含重复行中的 data_0 到 data_4 的数据。我需要将其转换为受尊重的数据集下的列值。如果早期类别的数据丢失,是否有任何方法可以放置空白/空值。例如
TimeStamp,Block,No_of_requests
04:19:12,data_0,4
04:19:12,data_1,6
04:19:12,date_2,8
04:19:12,date_3,10
04:19:12,data_4,12
04:19:14,data_0,5
04:19:14,data_1,6
04:19:14,date_3,7
04:19:14,data_4,8
预期输出是
TimeStamp,data_0,data_1,data_2,data_3,data_4
04:19:12,4,6,8,10,12
04:19:14,5,6,,7,8
等等。它应该放置空数据,以防相应 data_x 的值不可用。
答案1
GNUawk
解决方案:
awk 'BEGIN{
FS = OFS = ",";
PROCINFO["sorted_in"] = "@ind_num_asc";
print "TimeStamp,data_0,data_1,data_2,data_3,data_4"
}
NR > 1{ a[$1][substr($2, 6) + 1] = $3 }
END{
for (i in a) {
printf "%s,", i;
for (j=0; j<=4; j++) printf "%s%s", a[i][j+1], (j == 4? ORS:OFS)
}
}' file
输出:
TimeStamp,data_0,data_1,data_2,data_3,data_4
04:19:12,4,6,8,10,12
04:19:14,5,6,,7,8
答案2
与 Roman 的答案类似,但对文件内容的硬编码较少
awk -F, -v OFS=, '
NR > 1 {data[$1][$2] = $3; blocks[$2]}
END {
PROCINFO["sorted_in"] = "@ind_str_asc"
# header
printf "TimeStamp"
for (block in blocks) {
printf "%s%s", OFS, block
}
print ""
# data
for (ts in data) {
printf "%s", ts
for (block in blocks) {
printf "%s%s", OFS, data[ts][block]
}
print ""
}
}
' file
TimeStamp,data_0,data_1,data_4,date_2,date_3
04:19:12,4,6,12,8,10
04:19:14,5,6,8,,7
请注意,您的示例数据使用“数据“ 和 ”日期“ 两个都。