O script abaixo faz o seguinte, acho que é isso que você queria:
- Se um contig do arquivo1 não estiver presente no arquivo2, imprima todas as linhas desse contig.
- Se estiver presente no arquivo2, então, para cada valor do arquivo1, imprima-o apenas se não for menor que qualquer valor contig do arquivo2 -10 ou maior que qualquer valor do arquivo2 +10.
#!/usr/bin/env perl
my (%file1, %file2);
## read file1, the 1st argument
open(F1,"$ARGV[0]");
while(<F1>){
chomp;
## Split the line on whitespace into the @F array.
my @F=split(/\s+/);
## Save all lines in the %file1 hash.
## $F[0] is the contig name and $F[1] the value.
## The hash will store a list of all values
## associated with this contig.
push @{$file1{$F[0]}},$F[1];
}
close(F1);
## read file2, the second argument
open(F2,"$ARGV[1]");
while(<F2>){
## remove newlines
chomp;
## save the fields into array @F
my @F=split(/\s+/);
## Again, save all values associated with each
## contig into the %file2 hash.
push @{$file2{$F[0]}},$F[1];
}
close(F2);
## For each of the contigs in file1
foreach my $contig (keys(%file1)) {
## If this contig exists in file 2
if(defined $file2{$contig}){
## get the list of values for that contig
## in each of the two files
my @f2_vals=@{$file2{$contig}};
my @f1_vals=@{$file1{$contig}};
## For each of file1's values for this contig
val1:foreach my $val1 (@f1_vals) {
## For each of file2's value for this contig
foreach my $val2 (@f2_vals) {
## Skip to the next value from file1 unless
## this one falls within the desired range.
unless(($val1 < $val2-10) || ($val1 > $val2+10)){
next val1;
}
}
## We will only get here if none of the values
## fell within the desired range. If so, we should
## print the value from file1.
print "$contig $val1\n";
}
}
## If this contig is not in file2, print the
## lines from file1. This will print all lines
## from file1 whose contig was not in file2.
else {
print "$contig $_\n" for @{$file1{$contig}}
}
}
Salve isso em um arquivo de texto (digamos foo.pl
), torne-o executável ( chmod a+x foo.pl
) e execute-o assim:
./foo.pl file1 file2
No seu exemplo, ele retorna:
$ foo.pl file1 file2
Contig2 68
Contig3 102
Contig7 79