我有两个文件(每个两列,按标签分割),我想根据第一列比较它们。如果第一列上的值在两个文件上都相同,我想使用第二列值创建一个新文件。另外,请注意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很新,所以我完全不知道如何做到这一点。如果有人可以帮助修改以前的脚本(或以不同的方式解决这个问题),我将非常感激。
提前致谢! ☺
答案 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的顺序相同。