免费注册 查看新帖 |

Chinaunix

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

[文本处理] 文本(行有几十万,列有20列以上)求和及求min最小值 要保证速度 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-06-23 16:28 |只看该作者 |倒序浏览
本帖最后由 chenteng168 于 2016-06-24 14:36 编辑

有这么一个文本a.txt,内容如下
20160101|42012319891122492X|602|10000|100|10000|
20160101|42012319891122492X|605|10000|200|20000|
20160101|420123197911215144|612|10000|30000|200|
1、红色部分为关键列
2、要求前两列关键列相同的,第三列求最小的值,后面的列求和
3、这只是个例子,实际上有N行、N列所以脚本不能写死
4、速度不能太慢(几分钟之内)

结果:

20160101|42012319891122492X|602|20000|300|30000|
20160101|420123197911215144|612|10000|30000|200|

论坛徽章:
54
2015亚冠之德黑兰石油
日期:2015-07-07 13:00:1615-16赛季CBA联赛之深圳
日期:2016-03-31 09:03:5415-16赛季CBA联赛之辽宁
日期:2016-05-09 20:38:15程序设计版块每日发帖之星
日期:2016-05-12 06:20:0015-16赛季CBA联赛之四川
日期:2016-05-13 15:19:4715-16赛季CBA联赛之福建
日期:2016-05-15 20:24:34每日论坛发贴之星
日期:2016-05-16 06:20:0015-16赛季CBA联赛之吉林
日期:2016-05-26 11:49:4715-16赛季CBA联赛之广东
日期:2016-05-26 13:49:18极客徽章
日期:2016-12-07 14:05:2315-16赛季CBA联赛之广夏
日期:2016-12-20 17:33:532017金鸡报晓
日期:2017-01-10 15:19:56
2 [报告]
发表于 2016-06-23 17:06 |只看该作者
你有尝试怎么折腾呢?

论坛徽章:
0
3 [报告]
发表于 2016-06-23 17:14 |只看该作者
我根本不会shell,只好来请教大神们了

论坛徽章:
769
金牛座
日期:2014-02-26 17:49:58水瓶座
日期:2014-02-26 18:10:15白羊座
日期:2014-04-15 19:29:52寅虎
日期:2014-04-17 19:43:21酉鸡
日期:2014-04-19 21:24:10子鼠
日期:2014-04-22 13:55:24卯兔
日期:2014-04-22 14:20:58亥猪
日期:2014-04-22 16:13:09狮子座
日期:2014-05-05 22:31:17摩羯座
日期:2014-05-06 10:32:53处女座
日期:2014-05-12 09:23:11子鼠
日期:2014-05-21 18:21:27
4 [报告]
发表于 2016-06-23 17:23 |只看该作者
本帖最后由 Herowinter 于 2016-06-23 17:27 编辑

回复 1# chenteng168

  1. awk -F\| '{a[$1FS$2];for(i=1;i<=NF;i++)if(length($i)){b[$1FS$2,i]+=$i;if(!($1FS$2 in c) || $3<c[$1FS$2])c[$1FS$2]=$3}} END{for(i in a){s=i""FS""c[i];for(j=4;j<=NF;j++)s=s""FS""b[i,j];print s}}' i
  2. 20160101|420123197911215144|612|10000|30000|200|
  3. 20160101|42012319891122492X|602|20000|300|30000|
复制代码

论坛徽章:
5
金牛座
日期:2015-07-03 13:32:00卯兔
日期:2015-07-03 13:32:17程序设计版块每日发帖之星
日期:2015-11-29 06:20:0015-16赛季CBA联赛之同曦
日期:2015-12-15 09:36:06CU十四周年纪念徽章
日期:2016-07-06 17:18:48
5 [报告]
发表于 2016-06-23 17:30 |只看该作者
本帖最后由 seanking1987 于 2016-06-23 17:31 编辑

初学AWK者留贴路过~~写不出来

论坛徽章:
2
luobin
日期:2016-06-17 17:46:36lufei
日期:2016-06-17 17:49:16
6 [报告]
发表于 2016-06-23 17:48 |只看该作者
awk 博大精深

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
7 [报告]
发表于 2016-06-23 17:56 |只看该作者
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. my %hStat;
  5. while (<>){
  6.     my ($key, $min, $vals) = /\A((?:\w+\|){2})(\d+)\|((?:\d+\|)+)/g;
  7.     $vals = [split (/\|/, $vals)];
  8.     if (!exists ($hStat{$key})){
  9.         @{$hStat{$key}}{"Min", "Vals"} = ($min, $vals);
  10.         next;
  11.     }
  12.     my $Vals = $hStat{$key}{"Vals"};
  13.     $Vals->[$_] += $vals->[$_] for 0 .. scalar(@$vals) - 1;
  14.     $hStat{$key}{"Min"} = $min if ($hStat{$key}{"Min"} > $min);
  15. }

  16. print $_, join ("|", $hStat{"$_"}{"Min"}, @{$hStat{"$_"}{"Vals"}}, ""), "\n" for keys %hStat;
复制代码
20160101|420123197911215144|612|10000|30000|200|
20160101|42012319891122492X|602|20000|300|30000|

求职 : 技术支持/维
论坛徽章:
0
8 [报告]
发表于 2016-06-23 18:20 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
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
9 [报告]
发表于 2016-06-23 21:30 |只看该作者
回复 1# chenteng168

$ awk -F'|' '{k=$1 FS $2;if(a[k]==""||a[k]>$3)a[k]=$3;for(n=4;n<NF;++n)v[k,n]+=$n}END{for(k in a){p=k FS a[k] FS;for(n=4;n<NF;++n)p=p v[k,n] FS;print p}}' FILE
20160101|42012319891122492X|602|20000|300|30000|
20160101|420123197911215144|612|10000|30000|200|

   

论坛徽章:
0
10 [报告]
发表于 2016-06-24 01:54 |只看该作者
# awk -F '|' '{b[$1"|"$2] = 0 ; if (a[$1"|"$2,3] == 0 || $3 < a[$1"|"$2,3]) a[$1"|"$2,3]=$3; for(i=4;i<+NF;i++) a[$1"|"$2,i] += $i} END { for (i in b) {printf(i"|");for(j=3;j<NF;j++) printf(a[i,j]"|" );printf"\n"}}' q17
20160101|420123197911215144|612|10000|30000|200|
20160101|42012319891122492X|602|20000|300|30000|

用二维数组的方法试一下,感觉二维数组不是awk的强项。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP