Chinaunix

标题: 处理两个大文本 [打印本页]

作者: 清泉一边    时间: 2016-07-21 15:56
标题: 处理两个大文本
我有两个文件A.txt和B.txt;A,B行数相同。文件本身都比较大。

  1. A:
  2. aaaabbbbc
  3. bbbbgggk
  4. ddddddcddssdcs
  5. dashjkh
  6. hhhhgkkld
  7. B:
  8. aaaabbbdd
  9. cdddddaaahh
  10. ddddaaftte
  11. kjggakffl
  12. jjjjhsllljhhh
复制代码
现在想按这样的规则处理:如果A或者B至少有一个文件中有某行出现c,则删除二者对应的该行。例如A的第一行有c,则把A和B的第一行都提取出来分别输出到A删除.txt,B删除.txt,剩余的分别输出到A未删除.txt,,B未删除.txt。
因为文件比较大,不知道有没有比较省内存的方法?
作者: 清泉一边    时间: 2016-07-21 16:29
自己顶一下~等待大神出现!回复 1# 清泉一边


   
作者: sunzhiguolu    时间: 2016-07-21 18:17
本帖最后由 sunzhiguolu 于 2016-07-21 19:09 编辑

回复 1# 清泉一边
大神, 我就想问下 字母 c 所在的行 在文件 A, B 中所占的比例大概是多少?
另外, A, B 文件都比较大 有多大?

   
作者: 清泉一边    时间: 2016-07-21 19:26
大神取笑了
比例不会太高,一个文件2G左右,可是内存只有4G啊。回复 3# sunzhiguolu


   
作者: wxlfh    时间: 2016-07-21 19:37
本帖最后由 wxlfh 于 2016-07-21 19:39 编辑

按行处理,很省内存。只是两个文件都要读取两遍,算时间换内存吧
  1. use strict;

  2. my %del;

  3. open my $fh, "<", 'A.txt';
  4. while ( <$fh> ) {
  5.     chomp;
  6.     $del{$.} = 1 if /c/i;
  7. }

  8. open my $fh, "<", 'B.txt';
  9. while ( <$fh> ) {
  10.     chomp;
  11.     $del{$.} = 1 if /c/i;
  12. }

  13. open my $fh, "<", 'A.txt';
  14. open my $out,">", 'A_未删除.txt';
  15. while ( <$fh> ) {
  16.     print $out $_ unless exists $del{$.};
  17. }

  18. open my $fh, "<", 'B.txt';
  19. open my $out,">", 'B_未删除.txt';
  20. while ( <$fh> ) {
  21.     print $out $_ unless exists $del{$.};
  22. }
复制代码

作者: sunzhiguolu    时间: 2016-07-21 19:39
本帖最后由 sunzhiguolu 于 2016-07-21 19:44 编辑

如果比例不是很高的话, 我感觉将 A, B 中包含 "c" 的行最后写入一个文件, 反之 写入一个文件 是不是会提高点效率?
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. open (my $fhR, '<', './b');
  5. open (my $fhW, '>', './c');
  6. select ($fhW);

  7. my @adel;
  8. while (<>){
  9.     my $bLine = <$fhR>;
  10.     if (index ($_, 'c') >= 0 or index ($bLine, 'c') >= 0){
  11.         push (@adel, "a:$_", "b:$bLine");
  12.         next;
  13.     }
  14.     print "a:${_}b:$bLine";
  15. }

  16. close ($fhR);
  17. close ($fhW);
  18. select (STDOUT);
  19. print @adel;
复制代码
perl ab.pl a
----------------------------------------------------------
a:aaaabbbbc
b:aaaabbbdd
a:bbbbgggk
b:cdddddaaahh
a:ddddddcddssdcs
b:ddddaaftte

cat c
----------------------------------------------------------
a:dashjkh
b:kjggakffl
a:hhhhgkkld
b:jjjjhsllljhhh
作者: RE_HASH    时间: 2016-07-21 22:58
paste aa bb|grep -v c |cut -f1 > a_keep.txt &
paste aa bb|grep -v c |cut -f2 > b_keep.txt &
paste aa bb|grep c |cut -f1 > a_deleted.txt &
paste aa bb|grep c |cut -f2 > b_deleted.txt &

作者: yinyuemi    时间: 2016-07-22 09:16
回复 1# 清泉一边

这个意思?
  1. perl -e 'open(F1,"a");
  2. open(F2,"b");
  3. open(O1,">a.del");
  4. open(O2,">b.del");
  5. open(K1,">a.retain");
  6. open(K2,">b.retain");
  7. my $line;
  8. while(<F1>){
  9.   $line = $_;
  10.   $line2 = <F2>;
  11.   if($line =~ /c/ or $line2 =~ /c/){
  12.      print O1 $line;
  13.      print O2 $line2
  14.   }else{
  15.      print K1 $line;
  16.      print K2 $line2
  17.   }
  18. }'
复制代码

作者: 清泉一边    时间: 2016-07-22 15:20
大神就是大神!
  1. $line2 = <F2>;
复制代码
回复 8# yinyuemi


   
作者: 清泉一边    时间: 2016-07-22 15:22
这样用到了hash,如果比例过高,也害怕内存不够用,不过处理我的文本也够用了!谢谢!回复 5# wxlfh


   
作者: 清泉一边    时间: 2016-07-22 15:24
不错的想法! 谢谢!回复 6# sunzhiguolu


   
作者: 清泉一边    时间: 2016-07-22 15:25
谢谢!回复 7# RE_HASH


   
作者: wx2wx    时间: 2016-07-22 16:34
学习了
作者: wxlfh    时间: 2016-07-22 18:24
hash里存的是行号,而且存的只是要删除行的行号,内存是够的
回复 10# 清泉一边


   




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2