免费注册 查看新帖 |

Chinaunix

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

awk 多个文件列合并 求高效脚本 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-12-17 10:44 |只看该作者 |倒序浏览
文本1 a.txt
1 456798
2 456764
3 489743
5 136633

文本2 b.txt
1 1233
3 1324
4 1234

文本3 c.txt
1 1343
2 1343
3 1324
………………共六个txt

合并后效果如下

1        456798        1233        1343        ……
2        456764        0        1343        ……
3        489743        1324        1324        ……
4        0        1234        0        ……
5        136633        0        0        ……

论坛徽章:
0
2 [报告]
发表于 2010-12-17 10:46 |只看该作者
PS。TAB怎么整到帖子里

论坛徽章:
0
3 [报告]
发表于 2010-12-17 11:00 |只看该作者
awk '{a[$1]=a[$1]" "$2}END{for (i in a) printf("%s %s\n",i,a[i])}' f1 f2 f3 f4 f5 f6|sort

论坛徽章:
0
4 [报告]
发表于 2010-12-17 11:17 |只看该作者
其中的0,怎么加进去呀~~,不知了

论坛徽章:
0
5 [报告]
发表于 2010-12-17 11:19 |只看该作者
本帖最后由 bjsfeng 于 2010-12-17 11:21 编辑
其中的0,怎么加进去呀~~,不知了
finechore 发表于 2010-12-17 11:17



    我也在这地方犯难呢.... 现在想cat 出一个全部的$1的列表 然后把f1 f2 f3 f3 f5 f6补零 再awk到一起 但是文件都比较长 补零基本上要算一天

论坛徽章:
23
15-16赛季CBA联赛之吉林
日期:2017-12-21 16:39:27白羊座
日期:2014-10-27 11:14:37申猴
日期:2014-10-23 08:36:23金牛座
日期:2014-09-30 08:26:49午马
日期:2014-09-29 09:40:16射手座
日期:2014-11-25 08:56:112015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:0315-16赛季CBA联赛之山东
日期:2017-12-21 16:39:1915-16赛季CBA联赛之广东
日期:2016-01-19 13:33:372015亚冠之山东鲁能
日期:2015-10-13 09:39:062015亚冠之西悉尼流浪者
日期:2015-09-21 08:27:57
6 [报告]
发表于 2010-12-17 12:18 |只看该作者
回复 1# bjsfeng


一个问题,如果文本是这样的:
文本1 a.txt
1 456798
3 489743
5 136633

文本2 b.txt
1 1233
3 1324
4 1234

文本3 c.txt
1 1343
3 1324
………………共六个txt

就是所有的文件中都没有2,那么合并后2是不存在还是要都填0 ?

1        456798        1233        1343        ……
2        0        0        0       0        0        0
3        489743        1324        1324        ……
4        0        1234        0        ……
5        136633        0        0        ……

论坛徽章:
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
7 [报告]
发表于 2010-12-17 12:29 |只看该作者
本帖最后由 jason680 于 2010-12-17 12:30 编辑
我也在这地方犯难呢.... 现在想cat 出一个全部的$1的列表 然后把f1 f2 f3 f3 f5 f6补零 再awk到一 ...
bjsfeng 发表于 2010-12-17 11:19



嗯要一天.....

試試這個吧

file: item_combine.pl

  1. use strict;

  2. my @aItem=(["item"]);
  3. my $sCnt=0;
  4. my $sMax_item=0;

  5. sub get_data{
  6.   my ($sFile, $sCnt) = @_;
  7.   open(FHin, "<" , $sFile) or die "can't open $sFile\n";
  8.   while(<FHin>){
  9.     my($sItem, $sNum, $sX) = split;
  10.     if($sX){
  11.       print "got some error: $_";
  12.     }
  13.     $aItem[$sItem]->[$sCnt] = $sNum;
  14.     $sMax_item = $sItem if($sItem > $sMax_item);
  15.   }  
  16.   close FHin;
  17. }

  18. foreach(@ARGV){
  19.   $sCnt++;
  20.   $aItem[0]->[$sCnt] = $_;
  21.   get_data($_,$sCnt);
  22. }

  23. printf("%4s ", $aItem[0]->[0]);
  24. printf("%10s ",$_) foreach(@{$aItem[0]}[1..$sCnt]);
  25. print "\n";
  26. foreach my $sItem (1 .. $sMax_item){
  27.   printf("%-4d ",$sItem);
  28.   foreach (1 .. $sCnt){
  29.     printf("%10d ", $aItem[$sItem]->[$_]);
  30.   }
  31.   print "\n"
  32. }
复制代码
perl item_combine.pl a.txt b.txt c.txt

item      a.txt      b.txt      c.txt
1      11456798     211233     311343
2      12456764          0     321343
3      13489743     231324     331324
4             0     241234          0
5      15136633          0          0

(注:内容有改过)

论坛徽章:
0
8 [报告]
发表于 2010-12-17 13:18 |只看该作者
回复  bjsfeng


一个问题,如果文本是这样的:
文本1 a.txt
1 456798
3 489743
5 136633

文本2 ...
ly5066113 发表于 2010-12-17 12:18



按需求应该是为不存在~

当然 如果全0的话 也可以以后剔除掉

论坛徽章:
23
15-16赛季CBA联赛之吉林
日期:2017-12-21 16:39:27白羊座
日期:2014-10-27 11:14:37申猴
日期:2014-10-23 08:36:23金牛座
日期:2014-09-30 08:26:49午马
日期:2014-09-29 09:40:16射手座
日期:2014-11-25 08:56:112015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:0315-16赛季CBA联赛之山东
日期:2017-12-21 16:39:1915-16赛季CBA联赛之广东
日期:2016-01-19 13:33:372015亚冠之山东鲁能
日期:2015-10-13 09:39:062015亚冠之西悉尼流浪者
日期:2015-09-21 08:27:57
9 [报告]
发表于 2010-12-17 13:55 |只看该作者
回复 8# bjsfeng
  1. $ cat a.txt
  2. 1 456798
  3. 2 456764
  4. 3 489743
  5. 5 136633
  6. $ cat b.txt
  7. 1 1233
  8. 3 1324
  9. 4 1234
  10. $ cat c.txt
  11. 1 1343
  12. 2 1343
  13. 3 1324
  14. $ awk 'FNR==1{n++}{m=m>$1?m:$1;a[$1","n]=$2}END{for(i=1;i<=m;i++){printf i;for(j=1;j<=n;j++) printf "%8s",a[i","j]?a[i","j]:0;print ""}}' [abc].txt
  15. 1  456798    1233    1343
  16. 2  456764       0    1343
  17. 3  489743    1324    1324
  18. 4       0    1234       0
  19. 5  136633       0       0
复制代码
如果第一列有不连续的,这段代码会出现都为0的情况。
手头没有Linux环境,如果是GNU awk的话,可以多用一个数组来记录第一列,然后在END中用asort函数来排序,这样就不会有都为0的情况了。

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
10 [报告]
发表于 2010-12-17 14:03 |只看该作者
本帖最后由 cjaizss 于 2010-12-17 14:05 编辑

这个可以吗?
awk 'BEGIN{last=0}last!=ARGIND{last=ARGIND;for(i in a)a=a"\t"0;}
NF==2{x=strtonum($1);y=$2;if(x in a){$0=a[x];$NF=y;a[x]=$0;}else{for(i=1;i<ARGIND;i++)a[x]=a[x]"0\t";a[x]=a[x]""y;}}
END{for(i in a)b=i;count=asort(b);for(i=1;i<=count;i++)print b,a[b]}' a.txt b.txt c.txt
哦,有问题,等下我再改
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP