Chinaunix

标题: 新人求解 [打印本页]

作者: codeternity    时间: 2013-09-16 14:04
标题: 新人求解
各位大侠,最近刚开始学习perl,现遇到一个问题,关于文件合并的,虽然论坛里有好多这种问题,但我还是想求解一下自己的问题,拜托了……
我有两个文本,第一个为new1.txt:
SH    AA    XX
GZ    BB    YY
SZ    CC    ZZ
BJ     DD   WW
第二个为new2.txt
TJ    BB     OO
HN   CC     PP
HB   EE     QQ
HN   FF      RR
我想根据第二列中两个文本中共同的挑出来,输出到新的文本new.txt里,结果如下:
GZ    BB    YY
SZ    CC    ZZ
TJ    BB     OO
HN   CC     PP
不知道该咋实现,求各位大神不吝赐教
作者: yinyuemi    时间: 2013-09-16 14:26
回复 1# codeternity


    perl -anle 'print $hash{$F[1]}->[1],"\n",$_ if ++$hash{$F[1]}->[0] == 2; $hash{$F[1]}->[1]=$_;' file1 file2
作者: codeternity    时间: 2013-09-16 14:28
回复 2# yinyuemi
大神,这个有点看不懂……


   
作者: stanley_tam    时间: 2013-09-16 14:31
第一感觉用shell快点。。。{:3_188:}
  1. egrep -f new1.txt new2.txt > new.txt
复制代码

作者: codeternity    时间: 2013-09-16 14:37
回复 4# stanley_tam
大侠,我这个perl还没搞明白,您这个shell我恐怕又得……


   
作者: Cu_fans    时间: 2013-09-16 14:57
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. my %hash;
  5. open FH1, "<", "new1.txt" or die $!;
  6. open FH2, "<", "new2.txt" or die $!;
  7. while (<FH1>)
  8. {
  9.         chomp;
  10.         my $key = (split /\s+/)[1];
  11.         $hash{$key} = $_;
  12. }

  13. while (<FH2>)
  14. {
  15.         chomp;
  16.         my $key = (split /\s+/)[1];
  17.         if (exists $hash{$key})
  18.         {
  19.                 print qq/$hash{$key}\n/;
  20.                 print qq/$_\n/;
  21.         }
  22. }

  23. close FH2;
  24. close FH1;
复制代码
这个应该好理解了吧
作者: cinanine    时间: 2013-09-16 15:12
  1. perl -ape '$c{$F[1]}?($a.=$c{$F[1]})&&($b.=$_):($c{$F[1]}=$_)}{$_=$a.$b' new1.txt new2.txt > new.txt
复制代码

作者: yinyuemi    时间: 2013-09-16 17:03
回复 3# codeternity
  1. #!/usr/bin/perl

  2. use strict;

  3. my %hash;


  4. open(f1,"file1") or die "$!\n";
  5. open(f2,"file2") or die "$!\n";

  6. while(<f1>){
  7.     my $data = split;
  8.     $hash{$data[1]}->[0]++;     
  9.     $hash{$data[1]}->[1] = $_;  
  10. }

  11. # the value of %hash is the ref of array, [counts of column2, data of one line];

  12. while(<f2>){
  13.     $hash{$data[1]}->[0]++;
  14.     if($hash{$data[1]} == 2){
  15.         print $hash{$data[1]}->[1],$_;
  16.     }
  17. }

  18. close(f1);
  19. close(f2);
复制代码

作者: 神之战戟    时间: 2013-09-16 18:41
回复 7# cinanine


这个是不是写了一部分啊
作者: grshrd49    时间: 2013-09-16 21:23
回复 7# cinanine


    灌个水!
每次看到你的头像我就想歪了!!!!!
作者: codeternity    时间: 2013-09-16 23:34
回复 6# Cu_fans
十分感谢大侠,按照您给出的程序,的确做出我想要的来了。
不过,我有个疑问如果
new1.txt为:
SH    CC    XX
GZ    BB    YY
SZ    CC    ZZ
BJ     DD   WW

new2.txt为:
TJ    BB      OO
HN   CC      PP
HB   EE      QQ
HN   FF      RR
二者得出的结果应该是:
GZ    BB    YY
TJ     BB    OO
SH    CC    XX   
SZ    CC    ZZ
HN   CC      PP

但结果却是:
HN   CC     PP
SH    CC    XX
TJ   BB     OO
GZ    BB    YY
HN   CC     PP
SZ    CC    ZZ
我就是想问当一个文件里的第二列值有重复的话,该怎么办呢
作者: inchonline    时间: 2013-09-17 01:04
回复 8# yinyuemi
要修改为如下才能得出结果:
#!/usr/bin/perl

use strict;

my %hash;


open(f1,"file1") or die "$!\n";
open(f2,"file2") or die "$!\n";
my @data;
while(<f1>){
    @data = split/\s+/;
    $hash{$data[1]}->[0]++;
    $hash{$data[1]}->[1] = $_;  
}

# the value of %hash is the ref of array, [counts of column2, data of one line];

while(<f2>){
    @data = split/\s+/;
    $hash{$data[1]}->[0]++;
    if($hash{$data[1]} ->[0]== 2){
        print $hash{$data[1]}->[1],$_;
    }
}

close(f1);
close(f2);


   
作者: inchonline    时间: 2013-09-17 01:04
回复 8# yinyuemi
要修改为如下才能得出结果:
#!/usr/bin/perl

use strict;

my %hash;


open(f1,"file1") or die "$!\n";
open(f2,"file2") or die "$!\n";
my @data;
while(<f1>){
    @data = split/\s+/;
    $hash{$data[1]}->[0]++;
    $hash{$data[1]}->[1] = $_;  
}

# the value of %hash is the ref of array, [counts of column2, data of one line];

while(<f2>){
    @data = split/\s+/;
    $hash{$data[1]}->[0]++;
    if($hash{$data[1]} ->[0]== 2){
        print $hash{$data[1]}->[1],$_;
    }
}

close(f1);
close(f2);


   
作者: rubyish    时间: 2013-09-17 03:35
试试:
  1. #!/usr/bin/perl
  2. my %h;
  3. open my $N1, 'new1.txt';
  4. open my $N2, 'new2.txt';
  5. map { $h{ (split)[1] } .= $_ } <$N1>;

  6. while (<$N2>) {
  7.     my $k = (split)[1];
  8.     !$h{$k} and next;
  9.     $h{$k} eq $0 or ( $_, $h{$k} ) = ( $h{$k} . $_, $0 );
  10.     print;
  11. }
复制代码

作者: codeternity    时间: 2013-09-17 10:23
回复 14# rubyish
谢谢大神,真的可以,不过可不可以按每个文本输出结果,就是想把第一个文件的放一起,第二个放一起,比如上面的结果为:
SH    CC    XX
GZ    BB    YY
SZ    CC    ZZ
TJ   BB     OO
HN   CC     PP
上面三行是第一个文件的,下面的是第二个的……

   
作者: codeternity    时间: 2013-09-17 10:26
回复 6# Cu_fans
恩恩,这个理解起来要容易些。不过大侠我有个疑问,就是当第二列有重复的话,输出的结果好像不是很对……


   
作者: codeternity    时间: 2013-09-17 10:29
回复 8# yinyuemi
谢谢大侠的忠告,我会努力的。我总感觉自己在编程上少根弦,不会去思维……很是捉急啊……


   
作者: kernel69    时间: 2013-09-17 13:50
大牛,{$_=$a.$b多加了个{是什么意思?


回复 7# cinanine


   
作者: inchonline    时间: 2013-09-17 23:06
map { $h{ (split)[1] } .= $_ } <$N1>;
这行里,“.=”中间的点连接有什么用啊,去掉了运行也没有问题
回复 14# rubyish


   
作者: rubyish    时间: 2013-09-17 23:37
本帖最后由 rubyish 于 2013-09-17 22:03 编辑

回复 15# codeternity
  1. #!/usr/bin/perl
  2. my %h;
  3. open my $N1, 'new1.txt';
  4. open my $N2, 'new2.txt';
  5. my @N1 = map { my $k = (split)[1]; $h{$k} = 1; [ $k, $_ ] } <$N1>;
  6. my @N2 = map { my $k = (split)[1]; $h{$k} ? do { $h{$k}++; $_ } : () } <$N2>;
  7. print map( { $h{ $_->[0] } > 1 ? $_->[1] : () } @N1 ), @N2;
复制代码

作者: rubyish    时间: 2013-09-17 23:43
回复 21# inchonline
  1. my $H = 'hello';
  2. $H .= ' world!';
  3. say $H;   # hello world!
复制代码
.=
  1. GZ    BB    YY
  2. TJ    BB      OO
  3. SH    CC    XX
  4. SZ    CC    ZZ
  5. HN   CC      PP
复制代码
=
  1. GZ    BB    YY
  2. TJ    BB      OO
  3. SZ    CC    ZZ
  4. HN   CC      PP
复制代码

作者: rubyish    时间: 2013-09-18 04:24
回复 19# kernel69


    http://bbs.chinaunix.net/forum.p ... ;page=2#pid23894051
作者: kernel69    时间: 2013-09-18 11:25
感谢大牛{:3_200:}

回复 25# rubyish


   
作者: codeternity    时间: 2013-09-20 23:14
回复 24# rubyish
大侠,如查这两个文件是这样的:
new1.txt
SH    AA    XX
GZ    BB    YY
SZ    CC    ZZ
BJ     DD   WW
new2.txt
SH
GZ
SZ
BJ
TJ
HN
NB
我想根据第二个文件补全第一个文件,没有的用-代替,即
SH    AA    XX
GZ    BB    YY
SZ    CC    ZZ
BJ     DD   WW
TJ     -       -
HN    -       -
NB    -       -
应该怎么实现呢



   




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