如何比较两个文件的第一列但得到第二列(使用Perl)

时间:2016-11-22 17:30:18

标签: perl hash compare

我有两个文件(每个两列,按标签分割),我想根据第一列比较它们。如果第一列上的值在两个文件上都相同,我想使用第二列值创建一个新文件。另外,请注意FILE1第一列中的ID可以重复。基本上我有:

FILE1:

TRINITY_DN10001_c0_g1_i1     TRINITY_DN10001_c0_g1_TRINITY_DN10001_c0_g1_i1_g.84091_m.84091
TRINITY_DN100032_c0_g2_i1    TRINITY_DN100032_c0_g2_TRINITY_DN100032_c0_g2_i1_g.20078_m.20078
TRINITY_DN100032_c0_g2_i1    TRINITY_DN100032_c0_g2_TRINITY_DN100032_c0_g2_i1_g.42263_m.42263
.....
TRINITY_DN99985_c0_g1_i1     TRINITY_DN99985_c0_g1_TRINITY_DN99985_c0_g1_i1_g.21199_m.21199

FILE2:

TRINITY_DN100007_c0_g1_i1   GO:0001071,GO:0003674
TRINITY_DN100032_c0_g2_i1   GO:0000149,GO:0001775
.....
TRINITY_DN99997_c0_g1_i1    GO:0000166,GO:0001882

我需要这个:

TRINITY_DN100032_c0_g2_TRINITY_DN100032_c0_g2_i1_g.20078_m.20078    GO:0000149,GO:0001775
TRINITY_DN100032_c0_g2_TRINITY_DN100032_c0_g2_i1_g.42263_m.42263    GO:0000149,GO:0001775
.....

我认为这可以通过在Perl中组合两个哈希表来完成,不知何故类似to this answer

但我对Perl很新,所以我完全不知道如何做到这一点。如果有人可以帮助修改以前的脚本(或以不同的方式解决这个问题),我将非常感激。

提前致谢! ☺

1 个答案:

答案 0 :(得分:0)

文件有多大?它们小到足以记忆吗?他们排序了吗?

假设其中一个文件足够小以适应内存,您可以读取该文件并对其进行哈希处理 - 键是第一列,值是第二列。然后,读取另一个文件,检查散列是否存在,如果是,则打印出第二列(其中一列是散列中的值)。

假设我们有$file1$file2,且$file1足够小,我们就会得到这样的结果:

open my $fh, '<', $file1 or die "Can't read $file1: $!";
my %file1 = map { split /\t/, $_, 2 } <$fh>; # this slurps in the file, be sure you can fit it all in memory multiple times over!
close $fh;
open $fh, '<', $file2 or die "Can't read $file2: $!";
while (<$fh>) {
    my ($k, $v) = split /\t/, $_, 2;
    if ($file1{$k}) {
        print join("\t", $file1{$k}, $v), "\n";
    }
}

假设相同,但允许file1有重复:

open my $fh, '<', $file1 or die "Can't read $file1: $!";
my %file1;
while (<$fh>) {
    my ($k, $v) = split /\t/, $_, 2;
    push @{$file1{$k}}, $v;
}
close $fh;
open $fh, '<', $file2 or die "Can't read $file2: $!";
while (<$fh>) {
    my ($k, $v) = split /\t/, $_, 2;
    if ($file1{$k}) {
        print join("\t", $_, $v), "\n" for @{$file1{$k}};
    }
}

请注意,输出将使file1中的重复键始终与file1的顺序相同。