Primero, decir que este código viene del hilo
Comparar dos listas sin que cambie la posición publicado anteriormente.
Luego, decir que, en este caso, es mejor leer y almacenar primero el segundo archivo, ya que luego, al recorrer el primer archivo, con independencia de si hay o no coincidencia, sacaremos todas las líneas del primer archivo. Al hacerlo así, el mismo bucle de lectura se convierte en el de escritura del resultado.
Esta es una posible solución:
Using perl Syntax Highlighting
#!/usr/bin/env perl
#
# Unir tablas de predicciones extracelulares
# Joaquín Ferrero, 2014.01.12
#
# Este programa lee dos archivos con datos en columnas, con un tabulador como delimitador.
#
# Los dos archivos contienen un ID numérico en la primera columna.
#
# El objetivo es sacar los datos del primer archivo unidos a los datos del segundo archivo, en aquellas líneas coincidentes por ID,
# o los datos del primer archivo, junto con el texto 'no hit', que no coincidan con ningún ID del segundo archivo.
#
# Uso:
# perl join_predictions.pl file1 file2
#
# Salida:
# Archivo list.txt
#
use v5.16;
use autodie;
## Comprobación de los argumentos de entrada
@ARGV == 2 or die "Uso: perl $0 file1 file2\n";
my($file1, $file2) = @ARGV;
-f $file1 or die "ERROR: No encuentro el archivo [$file1]\n";
-f $file2 or die "ERROR: No encuentro el archivo [$file2]\n";
## Lectura del archivo segundo (el dependiente)
open my $fh2, '<', $file2;
my %file2;
while (my $linea = <$fh2>) {
chomp $linea;
my($id2, @datos2) = split /\t/, $linea;
$file2{ $id2 } = [ @datos2 ];
}
close $fh2;
## Apertura del archivo de salida y del primer archivo (el independiente). Procesado
open my $fh1, '<', $file1;
open my $fh3, '>', 'list.txt';
my $n = 0;
my $iguales = 0;
while (my $linea = <$fh1>) {
chomp $linea;
my($id1, @datos1) = split /\t/, $linea;
next if $id1 !~ /^\d+$/; # pasa a la siguiente si el ID no es un número (evitar líneas de cabecera)
my @datos = ($id1, @datos1); # composición de los datos definitivos que imprimiremos
if ($file2{$id1}) { # si existe alguna línea en el segundo archivo con ese ID,
my @datos2 = @{$file2{$id1}}; # recuperamos los datos del segundo archivo
push @datos, @datos2[1..5]; # y los unimos a los del primero
$iguales++;
}
else { # si no, no hay coincidencia, así que informamos de ello
push @datos, 'no hit';
}
say $fh3 join "\t", @datos; # y los sacamos fuera
$n++;
}
close $fh1;
close $fh3;
say "\t\tRESULTADOS";
say "Tienes $n ID en tu lista $file1";
say "Se identificaron $iguales ID de la lista $file1 en la lista $file2";
__END__
Coloreado en 0.003 segundos, usando
GeSHi 1.0.8.4
La salida en pantalla, con los archivos que has adjuntado, es:
Using text Syntax Highlighting
RESULTADOS
Tienes 2624 ID en tu lista lista1.txt
Se identificaron 26 ID de la lista lista1.txt en la lista lista2.txt
Coloreado en 0.000 segundos, usando
GeSHi 1.0.8.4
Las primeras líneas del archivo de salida son:
Using text Syntax Highlighting
340513771 124295 Treesei EGR44057.1 20 0.917 YES no hit
340513772 82662 Treesei EGR44058.1 19 0.722 YES 7.00E-088 Sm7 AAZ80394 Trichoderma virens 87.15490196
340513779 71092 Treesei EGR44064.1 22 0.679 YES no hit
340513792 112649 Treesei EGR44075.1 29 0.506 YES no hit
340513800 73102 Treesei EGR44082.1 18 0.728 YES no hit
Coloreado en 0.000 segundos, usando
GeSHi 1.0.8.4