awk不支持多维数组, 在官方的文档中所说的多维数组并不是传统语言所说的多维数组,awk的多维数组是如:
awk '{ if (max_nf < NF) max_nf = NF max_nr = NR for (x = 1; x <= NF; x++) vector[x, NR] = $x } END { for (x = 1; x <= max_nf; x++) { for (y = max_nr; y >= 1; --y) printf("%s ", vector[x, y]) printf("\n") } }'
在某些情况下需要使用传统多维数组的方式对数据进行统计,生成例如
arr[key] = [field1, filed2, filed3]
这样的数据结构,虽然awk默认不支持这样的数据结构,但是我们可以自己以另一种方式实现,比如上面的数据结构可以变成这样:
arr[key] = "field1@field2@field3"; split(arr[key], arr2, "@")
就是以字符串分割的方式,然后再用split还原, 下面是一个例子,统计下面文件中第一个field重复行的后面字段进行相加,并添加几个filed实现比例统计, 文件是这样的, file.txt:
1270022377 17 0 0 0 0.00 0.00 0.00 1270022399 9 0 0 0 0.00 0.00 0.00 1270022377 17 0 0 0 0.00 0.00 0.00 1270538893 16 8 2 0 50.00 12.50 0.00 1270022399 9 0 0 0 0.00 0.00 0.00 1270538893 16 8 2 0 50.00 12.50 0.00
shell:
awk 'BEGIN{print("Ad View Hit Reg Pay Hit(%) Reg(%) Pay(%)");} \ 1{if($1 in a) { \ split(a[$1], b, "@"); \ a[$1]=sprintf("%s@%s@%s@%s@%s", $1, int($2)+int(b[2]), int($3)+int(b[3]), int($4)+int(b[4]), int($5)+int(b[5])); } \ else { \ a[$1]=sprintf("%s@%s@%s@%s@%s", $1, int($2), int($3), int($4), int($5))} \ }; \ END{for(line in a) { \ split(a[line], c, "@"); \ printf("%s %s %s %s %s %.2f %.2f %.2f\n", c[1], c[2], c[3], c[4], c[5], \ int(c[3])/int(c[2])*100, \ int(c[4])/int(c[2])*100, \ int(c[5])/int(c[2])*100); \ }}' file.txt
结果:
Ad View Hit Reg Pay Hit(%) Reg(%) Pay(%) 1270538893 32 16 4 0 50.00 12.50 0.00 1270022377 34 0 0 0 0.00 0.00 0.00 1270022399 18 0 0 0 0.00 0.00 0.00
2010-04-08 13:36:07, 3813 reviews, comment
send to mailbox
Shell script to backup all MySQL database
【转载】命令的小总结
MySQL Innodb备份
shell中的数组
一些shell技巧
( ),{ }的区别
一个小命令
awk同时操作两个文件
shell小技巧
Shell: 统计MySQL InnoDB表的大小
继续凸墙 for Mac OS
json_formatter
少年,不点下广告吗!
all by shitou
blog comments powered by Disqus