忘记密码   免费注册 查看新帖 |

ChinaUnix.net

  平台 论坛 博客 文库 频道自动化运维 虚拟化 储存备份 C/C++ PHP MySQL 嵌入式 Linux系统
12下一页
最近访问板块 发新帖
查看: 4669 | 回复: 15

关键字重复内容提取 [复制链接]

论坛徽章:
0
发表于 2018-04-05 06:10 |显示全部楼层
大家好,我想以文件的第一列为关键字,对关键字为重复的所在行内容进行提取,如下所示

data1.txt
---------
a 1 2
b 1 3
a 1 4
a 1 2
b 2 3
c 2 4
c 2 2
d 2 1
e 3 2

想输出的结果为:
data2.txt
---------
a 1 2
b 1 3
a 1 4
a 1 2
b 2 3
c 2 4
c 2 2

我自己写了一个脚本(就是不同的脚本拼了拼),虽然可以输出结果但感觉太冗长了,贴出来请大家看看,请大家能给些建议,也请教大家能给些简便脚本供自己参考学习一下。
此外,对关键字进行排序和不排序两种情况进行输出,该分别如何写呢?

#不排序结果
a 1 2
b 1 3
a 1 4
a 1 2
b 2 3
c 2 4
c 2 2

#排序结果
a 1 2
a 1 2
a 1 4
b 1 3
b 2 3
c 2 2
c 2 4

#!/usr/bin/perl -w

open IN1, "data1.txt";

while (<IN1>) {
        chomp;
        @array1=split;
        push @array2,$array1[0];
}

close IN1;

my $key;
my $value;
my %hash;
foreach (@array2){
++$hash{$_};
}

while(($key,$value)=each %hash){
        if ($value>=2) {
        push @array3,$key;
        }
}

open IN2,"data1.txt";
open OUT,">data2.txt";

my %name = map {/^(\S+)/,1 } @array3;
map { $name{ (split)[0] } and print OUT $_ } <IN2>;

close IN2;
close OUT;

多谢各位了


论坛徽章:
37
CU大牛徽章
日期:2013-03-13 15:32:35CU十二周年纪念徽章
日期:2013-10-24 15:41:34射手座
日期:2013-10-24 21:01:23辰龙
日期:2013-12-20 17:07:19狮子座
日期:2014-05-12 11:00:00寅虎
日期:2014-06-04 16:25:27IT运维版块每日发帖之星
日期:2015-08-17 06:20:002015亚冠之首尔
日期:2015-11-04 22:25:43数据库技术版块每日发帖之星
日期:2015-12-01 06:20:00平安夜徽章
日期:2015-12-26 00:06:30IT运维版块每日发帖之星
日期:2016-01-27 06:20:0015-16赛季CBA联赛之新疆
日期:2016-06-07 14:10:01
发表于 2018-04-05 10:55 |显示全部楼层
我有一个想法,就是把这些数据导入到sqlite(mysql)里面去
然后count, sum, having ,
sql 随便怎么折腾了

论坛徽章:
0
发表于 2018-04-05 12:22 |显示全部楼层
newfinder 发表于 2018-04-05 06:10
大家好,我想以文件的第一列为关键字,对关键字为重复的所在行内容进行提取,如下所示

data1.txt

Excel不用,为什么要用perl?
能够土法炼钢,为什么要编程?
excel 2010开始菜单下有条件格式,
条件格式下有重复值,对重复值设置某一种颜色
然后筛选重复值,就达到你的要求了.


01.png
02.png
03.png

论坛徽章:
0
发表于 2018-04-05 12:26 |显示全部楼层
我是perl菜鸟,我觉得先用循环的方式生成hash,然后输出大于等于2的
不过我能用Excel绝对不用perl
Excel多简单呀

论坛徽章:
0
发表于 2018-04-05 15:36 |显示全部楼层
回复 2# laputa73

尴尬了,我不会mysql哦~~

论坛徽章:
0
发表于 2018-04-05 15:38 |显示全部楼层
回复 4# xiaomm250

是个好主意。不过EXCEL对于小数据还可以,但是数据量大的话就不是那么方便了。我列的这个数据只是一个示例,实际数据要比这个大很多。

论坛徽章:
0
发表于 2018-04-05 16:37 |显示全部楼层
newfinder 发表于 2018-04-05 15:38
回复 4# xiaomm250

是个好主意。不过EXCEL对于小数据还可以,但是数据量大的话就不是那么方便了。我列 ...
  1. use strict;
  2. use warnings;
  3. open(File1,'<data1.txt') or die "can not open file:$!\n";my @data1=<File1>;close(File1);
  4. open(File2,'>data2.txt') or die "can not open file:$!\n";
  5. my %firstcol=();#第一列的hash
  6. #先获取第一列的hash的值的计数
  7. foreach my $line1(@data1)
  8. {
  9.     if($line1=~m/^(\S+)/)
  10.     {
  11.         $firstcol{$1}++;
  12.     }else
  13.     {
  14.         print File2 "9527你大爷有错误!\n";
  15.     }
  16. }
  17. #通过循环,如果计数大于1,则输出
  18. foreach my $line1(@data1)
  19. {
  20.     if($line1=~m/^(\S+)/ and $firstcol{$1}>1)
  21.     {
  22.         print File2 $line1;
  23.     }
  24. }
  25. close(File1);
  26. close(File2);
  27. #先排序文本,然后第一列计数大于壹的就打印出来
  28. open(File3,'>data3.txt') or die "can not open file:$!\n";
  29. my @newdata1=sort(@data1);#排序后的data1
  30. foreach my $line1(@newdata1)
  31. {
  32.     if($line1=~m/^(\S+)/ and $firstcol{$1}>1)
  33.     {
  34.         print File3 $line1;
  35.     }
  36. }
  37. close(File3);
复制代码
这是我写的代码,能得到你的运行结果,还有注释,可能效率不是那么理想,我测试了400w行,十几秒能得到结果,我win8 32bit

论坛徽章:
0
发表于 2018-04-05 16:41 |显示全部楼层
xiaomm250 发表于 2018-04-05 16:37
这是我写的代码,能得到你的运行结果,还有注释,可能效率不是那么理想,我测试了400w行,十几秒能得到结果,我 ...

稍微改进一下代码就是先读取data2的文本,然后直接排序然后输出就可以了

论坛徽章:
0
发表于 2018-04-05 16:46 |显示全部楼层
  1. use strict;
  2. use warnings;
  3. open(File1,'<data1.txt') or die "can not open file:$!\n";my @data1=<File1>;close(File1);
  4. open(File2,'>data2.txt') or die "can not open file:$!\n";
  5. my %firstcol=();#第一列的hash
  6. #先获取第一列的hash的值的计数
  7. foreach my $line1(@data1)
  8. {
  9.     if($line1=~m/^(\S+)/)
  10.     {
  11.         $firstcol{$1}++;
  12.     }else
  13.     {
  14.         print File2 "9527你大爷有错误!\n";
  15.     }
  16. }
  17. #通过循环,如果计数大于1,则输出
  18. foreach my $line1(@data1)
  19. {
  20.     if($line1=~m/^(\S+)/ and $firstcol{$1}>1)
  21.     {
  22.         print File2 $line1;
  23.     }
  24. }
  25. close(File2);
  26. #读取data2的文本,然后排序,这样排序更快一些
  27. open(File2,'<data2.txt') or die "can not open file:$!\n";my @data2=<File2>;close(File2);
  28. open(File3,'>data3.txt') or die "can not open file:$!\n";
  29. my @newdata2=sort(@data2);#排序后的data2
  30. foreach my $line1(@newdata2)
  31. {
  32.     print File3 $line1;
  33. }
  34. close(File3);
复制代码


改进后的代码

我是perl菜鸟,我还读不懂你的代码

论坛徽章:
0
发表于 2018-04-05 17:35 |显示全部楼层
回复 9# xiaomm250

我也是菜鸟一枚呀,可以互相学习学习。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号 北京市公安局海淀分局网监中心备案编号:11010802020122
广播电视节目制作经营许可证(京) 字第1234号 中国互联网协会会员  联系我们:wangnan@it168.com
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP