免费注册 查看新帖 |

Chinaunix

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

一个Perl对文本处理问题!急,请高手赐教 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-12-25 17:00 |只看该作者 |倒序浏览
现描述如下:一个文件中的内容如下:
DS-SERVER-0001|1|0|0
DS-SERVER-0001|1|0|0
DS-SERVER-0001|2|0|0
DS-SERVER-0001|1|0|0
null|0|0|0
null|0|0|0
DS-SERVER-0001|1|0|0
DS-SERVER-0001|1|0|0
DS-SERVER-0001|19|0|0
DS-SERVER-0001|0|0|0
DS-SERVER-0009|0|0|0
DS-SERVER-0009|0|0|0
DS-SERVER-0001|0|0|0
DS-SERVER-0011|0|0|0
现在要进行如下处理:将每一行的第一个元素比如说"DS-SERVER-0001"凡是每行第一个元素和它相同的,只能出现一次,并且要求后面三项比如说1|0|0要和其相同的项依次相加比如说另一行为19|0|0,其各项相加后的结果就为20|0|0即1和19相加,0和0相加,0和0相加,总之要保证每行第一个元素相同的行只能出现一次,后面3个元素分别累计求和
上面的最终结果应该是这样的:

DS-SERVER-0001|26|0|0
null|0|0|0
DS-SERVER-0009|0|0|0
DS-SERVER-00011|0|0|0

论坛徽章:
0
2 [报告]
发表于 2007-12-25 17:30 |只看该作者
用关联数组,取得第一部分作为key,后面的作为value。
每读取一行,判断关联数组里面是否已经存在此key,有:取出值与现在的值分别split后对应相加,存之;没有则直接存之。
最后把关联数组全部输出即可。

效率不是最高的,但很简单。

论坛徽章:
0
3 [报告]
发表于 2007-12-26 09:44 |只看该作者
我以前是用二维数组写的,到最后实在是写不下去了,想要的功能也没实现,急啊^^谁能给我个用关联数组实现的代码?

论坛徽章:
0
4 [报告]
发表于 2007-12-26 10:19 |只看该作者
#!/USR/bin/perl -w
use strict;
my $file='file.txt';
my %tt;
open FH,$file || die "cant open $file \n";
while (<FH>) {
  my @one_line=split ("|",$_);
  ($tt{$one_line[0]})->[0]+=$one_line[1] ;
  ($tt{$one_line[0]})->[1]+=$one_line[2] ;
  ($tt{$one_line[0]})->[2]+=$one_line[3] ;
      }

论坛徽章:
0
5 [报告]
发表于 2007-12-26 11:33 |只看该作者
2楼兄弟!能给个代码实现吗?等着交,我是刚开始学Perl的,谢谢了

论坛徽章:
0
6 [报告]
发表于 2007-12-26 13:35 |只看该作者
$tt{$one_line[0]})->[0]+=$one_line[1] 这一句中“->[0]”是什么意思?楼上给解释一下把

论坛徽章:
0
7 [报告]
发表于 2007-12-26 13:41 |只看该作者
4楼都给你写好了(没有看到?),再加上输出就可以了。
use strict;
my $file='file.txt';
my %tt;
my $key;
open FH,$file || die "cant open $file \n";
while (<FH>) {
        my @one_line=split (/\|/,$_);
  ($tt{$one_line[0]})->[0]+=$one_line[1] ;
  ($tt{$one_line[0]})->[1]+=$one_line[2] ;
  ($tt{$one_line[0]})->[2]+=$one_line[3] ;
}
foreach $key (sort keys %tt){
        print "$key\|$tt{$key}->[0]\|$tt{$key}->[1]\|$tt{$key}->[2]\n";
}

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
8 [报告]
发表于 2007-12-26 13:49 |只看该作者
  1. flw@debian:~$ cat foo
  2. DS-SERVER-0001|1|0|0
  3. DS-SERVER-0001|1|0|0
  4. DS-SERVER-0001|2|0|0
  5. DS-SERVER-0001|1|0|0
  6. null|0|0|0
  7. null|0|0|0
  8. DS-SERVER-0001|1|0|0
  9. DS-SERVER-0001|1|0|0
  10. DS-SERVER-0001|19|0|0
  11. DS-SERVER-0001|0|0|0
  12. DS-SERVER-0009|0|0|0
  13. DS-SERVER-0009|0|0|0
  14. DS-SERVER-0001|0|0|0
  15. DS-SERVER-0011|0|0|0
  16. flw@debian:~$ perl -F'\|' -lane '$h{$F[0]}->[$_-1]+=$F[$_] for(1..3); END{print join("|", $_, @{$h{$_}}) for sort keys %h}' foo
  17. DS-SERVER-0001|26|0|0
  18. DS-SERVER-0009|0|0|0
  19. DS-SERVER-0011|0|0|0
  20. null|0|0|0
  21. flw@debian:~$
复制代码

论坛徽章:
0
9 [报告]
发表于 2007-12-26 14:37 |只看该作者

appreciate!!

搞定了,谢谢各位大哥了

论坛徽章:
0
10 [报告]
发表于 2007-12-27 20:46 |只看该作者

回复 #8 flw 的帖子

版主可否把这个命令行转换成win下面的格式?我用下面的这个怎么不行呢?
  1. perl -F^| -lane "$h{$F[0]}->[$_-1]+=$F[$_] for(1..3); END{print join('|', $_, @{$h{$_}}) for sort keys %h}" o.txt
复制代码

结果是:
D|0|0|0
n|0|0|0

o.txt 文件的内容和你foo文件的内容一样。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP