LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1300|回复: 7

[求助]awk 数组使用.

[复制链接]
发表于 2007-8-9 18:02:24 | 显示全部楼层 |阅读模式
现在有一些这样的数据
  1.   0.0  7504 ARSMgnt_test
  2.   0.0  7506 ARSMgnt_test
  3.   0.0 33548 ARSWarnMgnt_test
  4.   0.0 32888 ARSogMgnt_test
  5.   0.0 32888 ARSogMgnt_test
  6.   0.0 32892 ARSogMgnt_test  
  7.   0.0 37476 ARSustMgnt_test
  8.   0.0 18608 ARSlegeMgnt_test
  9.   0.0  6740 ARSactMgnt_test
  10.   0.0 41232 ARSgnt_test
  11.   0.0 33400 ARSgnt_test
  12.   0.0  5992 ARSgntSef_test
  13.   0.0  4132 ARServiceMgnt_test
  14.   0.0 33040 ARSgnt_test
  15.   0.0 26892 ARSgnt_test
  16.   0.0 56916 ARSusiMgnt_test
  17.   0.0 64456 ARSQueryInfo_test
  18.   0.0 60140 ARSsMgnt_test
  19.   0.0  7428 ARSmgnt_test
  20.   0.0 60832 ARSBatchTask_test
  21.   0.0 71440 ARSPortalMgnt_test
  22.   0.0 71441 ARSPortalMgnt_test
  23.   0.0 31720 ARSgnt_test
  24.   0.0 36120 ARSMgnt_test
  25.   0.0 24012 ARSontrol_test
  26.   0.0 36872 ARSVipMgnt_test
  27.   0.0 63512 ARSgnt_test
  28.   0.0  5932 ARSamMgnt_test
  29.   0.0 51244 ARShanceMgnt_test
  30.   0.0  6272 ARSemgnt_test
  31.   0.0 66232 ARSgnt_test
复制代码

需要完成的功能,将所有低三列同名的记录,分别将第1列和第2列的数值相加.如
  1.   0.0 32888 ARSogMgnt_test
  2.   0.0 32888 ARSogMgnt_test
  3.   0.0 32892 ARSogMgnt_test  
复制代码

处理后变为
  1. 0.0 98668 ARSogMgnt_test
复制代码

想用awk的数组来实现..  或者用其他工具.
请大家多帮帮忙... 谢谢先~~!
发表于 2007-8-9 18:36:50 | 显示全部楼层
try this:
  1. awk '{
  2.         name_a[$3] = name_a[$3] + $1
  3.         name_b[$3] = name_b[$3] + $2 };
  4.         END{
  5.                 for (i in name_a)
  6.                         print name_a[i], name_b[i], i
  7.         }' <filename>
复制代码
数组name_a与name_b的组成是一样的, 但是成员的值不同.

ps: 建议关于shell编程(包括sed, awk)的问题发到 "Linux shell进阶应用与shell编程" 版, 获得帮助的概率要大一些.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-8-9 20:16:38 | 显示全部楼层
谢谢楼上的,我现在44看.

不好意思,发帖子的时候网络比较慢.没注意看. 麻烦斑竹帮我移到shell 板块.谢谢!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-8-10 00:13:09 | 显示全部楼层
能不能帮忙解释一下么? 我看了半天的man都没明白.  3q!
回复 支持 反对

使用道具 举报

发表于 2007-8-10 11:38:32 | 显示全部楼层
解释一下 (因为name_a与name_b作用相似, 前者处理第一列, 后者处理第二列, 因此只分析name_a):
假设<filename>的内容是:
7 13 a
2 31 b
3 33 a
9 34 b

则在处理之前: name_a 为空数组
处理第一行前, name_a['a']=0; 处理中: $1=7, $3='a', name_a['a'] = 0 + 7; 处理后: name_a['a']=7

处理第二行前: name_a['b']=0; 处理中: $1=2, $3='b', name_a['b'] = 0 + 2; 处理后: name_a['a']=7, name_a['b']=2

处理第三行前, name_a['a']=7; 处理中: $1=3, $3='a', name_a['a'] = 7 + 3; 处理后: name_a['a']=10, name_a['b']=2

类似的, 处理第四行后, name_a['a']=10, name_a['b']=11

END段在全部文件处理完成后运行, i为name_a的下标值, 即i的取值为'a', 'b'. for循环将输出的name_a的值即为name_a['a']和name_a['b']的值, 分别为 10, 11.
回复 支持 反对

使用道具 举报

发表于 2007-10-23 12:45:12 | 显示全部楼层
请问如果想继续分别求相同列名的均值,该如何修改上面那段脚本。万分感谢
回复 支持 反对

使用道具 举报

发表于 2007-10-23 14:01:44 | 显示全部楼层
添加一个用来保存相同第三列的数组name_num即可:
  1. awk '{
  2.         name_num[$3]++
  3.         name_a[$3] = name_a[$3] + $1
  4.         name_b[$3] = name_b[$3] + $2 };
  5.         END{
  6.                 for (i in name_a)
  7.                         print name_a[i]/name_num[i], name_b[i]/name_num[i], i
  8.         }' <filename>
复制代码
回复 支持 反对

使用道具 举报

发表于 2007-10-24 00:14:52 | 显示全部楼层
chunchengfh:

太棒了,It works well.
非常非常感谢你的帮助
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表