-1

我想比较两个文件中的三列,第三列可以在-3到+3之间的范围内,给我两个文件的联合。文件 1

miR156a AT1G27360   1253
miR156a AT1G27370   2368
miR156a AT1G53160   586

文件 2

miR156a AT1G27360   1252    
miR156a AT1G27370   2367    
miR156a AT1G53160   123 
miR156a AT1G69170   1296

预期输出为

miR156a AT1G27360   1253
miR156a AT1G27370   2368
miR156a AT1G53160   586
miR156a AT1G53160   123 
miR156a AT1G69170   1296

我尝试编写一个 perl 脚本,在该脚本中我只能找到交集但无法获得两个文件的并集

open(FH1, "$filename1");
open(FH2, "$filename2");
while ( $line1 = <FH1> ) {
    chomp $line1;
    @temp = split(/\s+/, $line1);
    if ($#temp > 1) {
        push(@miR_TP, $temp[0]);
        push(@tar_TP, $temp[1]); 
        push(@start_TP, $temp[2]); 
    }
}
while ( $line2 = <FH2> ) {
    chomp $line2;
    @temp2 = split(/\s+/, $line2);
    if($#temp > 1) {
        push(@miR, $temp2[0]);
        push(@tar, $temp2[1]); 
        push(@start, $temp2[2]);        
    }
}
for ($i=0 ; $i<=$#miR ; $i++) {
    for($j=0 ; $j<=$#miR_TP ; $j++) {
        if (    ($miR[$i] eq $miR_TP[$j]) && 
            ($tar[$i] eq $tar_TP[$j]) &&
            (
                ($start[$i] eq $start_TP[$j])    ||
                ($start[$i] eq  $start_TP[$j]+1) ||
                ($start[$i] eq  $start_TP[$j]+2) ||
                ($start[$i] eq  $start_TP[$j]+3) ||
                ($start[$i] eq  $start_TP[$j]-1) ||
                ($start[$i] eq  $start_TP[$j]-2) ||
                ($start[$i] eq  $start_TP[$j]-3)
            )) {
            print "$miR[$i]\t$tar[$i]\t$start[$i]\n";
        }
    }
}

请帮助我修改代码。

4

1 回答 1

3

使用散列代替数组。而不是复杂的条件,使用abs函数:

#!/usr/bin/perl
use warnings;
use strict;

my $filename1 = 'file1';
my $filename2 = 'file2';

my %hash;

open my $FH, '<', $filename1 or die $!;

while (my $line = <$FH>)
{
    chomp $line;
    my ($mir, $tar, $start) = split ' ', $line;
    if (defined $start)
    {
        print $line, "\n";                   # Always show file 1.
        push @{ $hash{$mir}{$tar} }, $start;
    }
}

open $FH, '<', $filename2 or die $!;
while (my $line = <$FH>)
{
    chomp $line;
    my ($mir, $tar, $start) = split ' ', $line;
    unless (exists $hash{$mir}
            and exists $hash{$mir}{$tar}
            and grep 3 >= abs $start - $_, @{ $hash{$mir}{$tar} })
    {
              print $line, "\n";
    }
}
于 2013-01-22T16:09:19.600 回答