免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3459 | 回复: 10
打印 上一主题 下一主题

请教shell求和方法 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-04-17 16:54 |只看该作者 |倒序浏览
有一个文件cat abc
1 10
3 20
1 50
5 20
20 46
5  40


想实现这样的功能:
第一列按照1 3 5 10 20 排序,第二列进行求和.
如果第一列的值不存在,则第二列补充为0.
即最后想要的的结果是:

1 60
3 20
5 60
10 0
20 46

请教怎么解决?

论坛徽章:
0
2 [报告]
发表于 2011-04-17 17:38 |只看该作者
回复 1# lvyuancyx


    请问 一下! 在你第一列中没有的数字,你问什么还要加入啊!

  我这写了个第一列没有10的:

echo '1 10
3 20
1 50
5 20
20 46
5  40'|awk '{a[$1]+=$2}END{for(i in a)print i"\t"a}'|sort -n -k 1
1       60
3       20
5       60
20      46

论坛徽章:
0
3 [报告]
发表于 2011-04-17 17:51 |只看该作者
本帖最后由 lvyuancyx 于 2011-04-17 18:04 编辑

回复 2# db2-zhang


    因为统计数据中需要10的数据,可能在某一天里却没有这个10的数据.所以要填成0.

我写了一个但是不够精简,所以想求更好的方法

for val in 1 3 5 10 20
do
awk '{print $1}' abc |grep -w $val >/dev/null 2>&1
if [ $? -eq 0 ];then
awk -v vv=$val  '{if($1==vv){a[$1]+=$2}}END{for(i in a) print i,a}' abc
else
echo $val 0
fi
done

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
4 [报告]
发表于 2011-04-17 19:45 |只看该作者
回复  db2-zhang


    因为统计数据中需要10的数据,可能在某一天里却没有这个10的数据.所以要填成0.
...
lvyuancyx 发表于 2011-04-17 17:51



$ echo '1 10
3 20
1 50
5 20
20 46
5  40' | perl -lane 'BEGIN{$h{$_}=0 for(1,3,5,10,20)}{$h{$F[0]}+=$F[1]}END{for(sort{$a<=>$b}keys %h){print "$_\t$h{$_}"}}'
1        60
3        20
5        60
10        0
20        46

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
5 [报告]
发表于 2011-04-17 22:19 |只看该作者
本帖最后由 jason680 于 2011-04-18 11:10 编辑

只用awk的来实现,难真累人....
$ echo '1 10
3 20
1 50
5 20
20 46
5 40 ' |awk 'BEGIN{a["01"]=a["03"]=a["05"]=a[10]=a[20]=0}
{a[sprintf("%02s",$1)]+=$2}
END{n=asorti(a,s);for(t=1;t<=n;t++)printf("%d\t%s\n",s[t],a[s[t]])}'
1        60
3        20
5        60
10        0
20        46

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
6 [报告]
发表于 2011-04-17 22:39 |只看该作者
  1. awk '{a[$1]+=$2;b[$1]=$1;}END{x=asort(b);for(i=1;i<=x;i++)print b[i],a[b[i]]}'
复制代码

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
7 [报告]
发表于 2011-04-18 01:38 |只看该作者
回复 1# lvyuancyx
  1. echo "1 10
  2. 3 20
  3. 1 50
  4. 5 20
  5. 20 46
  6. 5  40" |awk 'NF==2{a[$1]+=$2;next}{print $1,a[$1]?a[$1]:"0"}' - <(echo "1
  7. 3
  8. 5
  9. 10
  10. 20")
  11. 1 60
  12. 3 20
  13. 5 60
  14. 10 0
  15. 20 46
复制代码

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
8 [报告]
发表于 2011-04-18 09:08 |只看该作者
这个就应该用蛮力解决,别为了一个特殊情况考虑算法
,直接把第一列必须有的数字追加到文件里,
然后就是求和了

论坛徽章:
0
9 [报告]
发表于 2011-04-18 10:55 |只看该作者
同意楼上的...

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
10 [报告]
发表于 2011-04-18 10:56 |只看该作者
学习学习!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP