我想比较两个文件中的三列,第三列可以在-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";
}
}
}
请帮我修改代码。
答案 0 :(得分: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";
}
}