在转置期间处理不存在的条目

handling non existent entries during transpose

我有一个数据文件,需要在 awk 中进行转置处理不存在的值。

id|type|cost|date|ship
0|A|223|201603|PORT
0|A|22|201602|PORT
0|A|422|201601|DOCK
1|B|3213|201602|DOCK
1|B|3213|201601|PORT
2|C|2321|201601|DOCK

我需要转换并得到输出

id|type|201601|201602|201603|
0|A|422.0|22.0|223.0|
1|B|3213.0|3213.0|n/a|
2|C|2321.0|n/a|n/a|

我正在尝试在 awk 中进行数据透视,但它不起作用。

awk -F"|" -v OFS="|" ' NR>1 { k= OFS ;id[k]++;date[]++;cost[k]= } END {printf("%s","id|type|");for(i in date) printf("%s|",i);print ""; for(i in id) { printf("%s|",i); for(j in date)  { if( (i) in cost) { printf("%s|", cost[i OFS j]);} else { printf("%s|","n/a")} } print "" } }  ' data.txt

正在打印。

id|type|201601|201602|201603|
0|A||||
1|B||||
2|C||||

你可以试试这个gnu awk:

awk 'BEGIN {FS=OFS="|"; PROCINFO["sorted_in"]="@ind_str_asc"} NR>1{hdr[]; map[ OFS ][] = } END {printf "%s", "id" OFS "type" OFS; for (i in hdr) printf "%s", i OFS; print ""; for (r in map) {printf "%s", r OFS; for (i in hdr) printf "%s%s", (map[r][i] == "" ? "n/a" : sprintf ("%.1f", map[r][i])), OFS; print ""}}' file

id|type|201601|201602|201603|
0|A|422.0|22.0|223.0|
1|B|3213.0|3213.0|n/a|
2|C|2321.0|n/a|n/a|

更具可读性awk:

awk 'BEGIN {
   FS=OFS="|"
   PROCINFO["sorted_in"]="@ind_str_asc"
}
NR > 1 {
   hdr[]
   map[ OFS ][] = 
}
END {
   # print header
   printf "%s", "id" OFS "type" OFS
   for (i in hdr)
      printf "%s", i OFS
   print ""
   # print body
   for (r in map) {
      printf "%s", r OFS
      for (i in hdr)
         printf "%s%s", (map[r][i] == "" ? "n/a" : sprintf ("%.1f", map[r][i])), OFS
      print ""
   }
}' file