Sab Jul 12, 2008 11:31 am
|
 |
Lugerius
Perlero Nuevo

|
Registrado: 12 Jul 2008
Mensajes: 5
|
|
| Comparar dos columnas de archivos diferentes |
|
|
¡Saludos a todos desde México!
Estoy empezando con Perl y estoy batallando mucho con este programita.
Tengo dos archivos de texto con el siguiente formato,
Archivo1.txt
| Código: |
AC000000000 0 0
AC100000000 0 0
AC1100KLP00 19 51.72
AC3030GEN15 7 30.91
AC4015GEN04 11 4.83
AC4017GEN04 0 4.41
AC4017GEN05 24 5.54
AC5001GEN05 66 6.68
AC5002FPC09 15 28.78
AC5002GEN05 16 8.88
AC5003GEN00 6 6.11
AC700000000 0 0 |
Archivo2.txt
| Código: |
AC1100KLP00 761.91 19
AC1300GEN06 #N/A #N/A
AC2100GEN05 #N/A #N/A
AC3030GEN15 49.77 7
AC3030GEN60 #N/A #N/A
AC4015GEN04 81.65 12
AC4017GEN04 #N/A #N/A
AC4017GEN05 93.65 24
AC5001GEN05 10.75 23 |
Lo que quiero que el programa haga es que cada uno de los elementos de la columna 1 del archivo1.txt se compare con todos los elementos de la columna 1 del archivo2.txt y cuando sean iguales escribir en un nuevo archivo3.txt el contenido de esas filas del archivo1.txt. Espero haberme explicado.
Es decir, en mi ejemplo el archivo3.txt debería quedar más o menos así:
| Código: |
AC1100KLP00 19 51.72
AC3030GEN15 7 30.91
AC4015GEN04 11 4.83
AC4017GEN04 0 4.41
AC4017GEN05 24 5.54
AC5001GEN05 66 6.68 |
Donde tengo la duda principalmente es en el algoritmo para comparar los elementos de las columnas 1 de los dos archivos.
No pongo código porque estoy bastante perdido en este asunto, no sé si con un while o metiendo las columnas en arreglos y con foreach, pero he intentado varias cosas y no obtengo los resultados esperados.
De este mismo foro, leí que podía pegar mis archivos en uno solo con el comando paste, pero aún así no sé cómo comparar completamente las dos columnas.
Espero puedan ayudarme y de antemano ¡gracias!
Atte.
Luis G. Mendoza |
|
|
|

Sab Jul 12, 2008 12:06 pm
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4018
Ubicación: Valladolid, España
|
|
|
|
|
Bienvenido a los foros de Perl en Español, Lugerius.
Pues tienes razón. Con un while y un hash, tienes solucionado el problema.
Si pones el código te podemos ir dando más pistas.
Aquí te pongo la solución, en forma de pseudocódigo.
| Perl: | #!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
# Leemos el fichero Archivo2 y almacenamos la primera columna como claves
# Abrimos los ficheros Archivo1 en lectura y Archivo3 en escritura
# Para todas las líneas de Archivo1
# Si la primera columna de Archivo1 está entre las claves de Archivo2
# Escribimos la línea de Archivo1 en el Archivo3
# Fin del bucle
# Cerramos los archivos abiertos
|
|
|
Sab Jul 12, 2008 12:27 pm
|
 |
Lugerius
Perlero Nuevo

|
Registrado: 12 Jul 2008
Mensajes: 5
|
|
|
|
|
Muchas gracias por tu ayuda, voy a leer un poco más sobre los hash y en cuanto tenga el código lo publico.
¡SALUDOS!
Atte.
Luis G. Mendoza |
|

Sab Jul 12, 2008 4:51 pm
|
 |
Lugerius
Perlero Nuevo

|
Registrado: 12 Jul 2008
Mensajes: 5
|
|
| Otra cosa |
|
|
Bueno ya funciona el script pero me parece que no es la mejor forma de hacerlo, de todas formas aquí pongo el código.
| Perl: | # Leemos el fichero Archivo2 y almacenamos la primera columna como claves
open(ORIG, "archivo2.txt");
our %hash = ();
our $elemento;
while ($elemento= <ORIG>){
chomp($elemento);
my @linea = (split "\t", $elemento);
$hash{$linea[0]} = 1;
}
# Abrimos los ficheros Archivo1 en lectura y Archivo3 en escritura
open(DATOS, "archivo1.txt");
open(OUT, ">archivo3.csv");
# Para todas las líneas de Archivo1
while (my $lineas= <DATOS>) {
chomp($lineas);
our $col1 = (split "\t", $lineas)[0];
foreach my $llave (keys %hash){
# Si la primera columna de Archivo1 está entre las claves de Archivo2
if ($col1 eq $llave) {
# Escribimos la línea de Archivo1 en el Archivo3
print OUT "$lineas\n";
}
# esta parte es la que no me queda...
else { print "$elemento"; }
}
} |
Lo que quiero agregar es esto último
| Perl: | # Escribimos la línea de Archivo1 en el Archivo3
print OUT "$lineas\n";
}
# esta parte es la que no me queda...
else { print "$elemento"; }
} |
Ahora quiero que una vez que haya agregado todas las líneas correspondientes del archivo1.txt al archivo3.csv, las líneas que están en el archivo2.txt y que no encontró en archivo1.txt se impriman en el archivo3.txt con el formato:
para que quede más o menos así:
| Código: |
AC1100KLP00 19 51.72
AC1300GEN06 0 0
AC2100GEN05 0 0
AC3030GEN15 7 30.91
AC3030GEN60 0 0
AC4015GEN04 11 4.83
AC4017GEN04 0 4.41
AC4017GEN05 24 5.54
AC5001GEN05 66 6.68 |
Espero su ayuda, ya estuve dándole vueltas a esto y no he podido completarlo.
De antemano ¡Gracias!
Atte.
Luis G. Mendoza |
|

Sab Jul 12, 2008 5:36 pm
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4018
Ubicación: Valladolid, España
|
|
|
|
|
Enhorabuena. Has conseguido resolver el primer problema.
Lo único, comentarte que los hash se suelen usar para 'recordar' cosas (por algo, también se les llama memoria asociativas). Así que se puede usar de otra forma más inteligente.
Aquí está mi solución. | Perl: | #!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
# Leemos el fichero Archivo2 y almacenamos la primera columna como claves
my %archivo2;
open(FICHERO2, '<Archivo2.txt') or die "$!\n";
while ( my $linea = <FICHERO2> ) {
my ($columna1) = split(" ", $linea);
$archivo2{$columna1} = $linea;
}
close(FICHERO2 );
# Abrimos los ficheros Archivo1 en lectura y Archivo3 en escritura
open(FICHERO1, '<Archivo1.txt') or die "$!\n";
open(FICHERO3, '>Archivo3.txt') or die "$!\n";
# Para todas las líneas de Archivo1
while ( my $linea = <FICHERO1> ) {
# Si la primera columna de Archivo1 está entre las claves de Archivo2
my ($columna1) = split(" ", $linea);
if ( $archivo2{$columna1} ) {
# Escribimos la línea de Archivo1 en el Archivo3
print FICHERO3 $linea;
# Borramos la clave de Archivo2
delete $archivo2{$columna1};
}
}
# Escribimos las líneas de Archivo2 que no se imprimieron
foreach my $clave ( keys %archivo2 ) {
print FICHERO3 "$clave 0 0\n";
}
# Cerramos los archivos abiertos
close(FICHERO1 );
close(FICHERO3 ); |
|
|

Lun Jul 14, 2008 10:12 am
|
 |
Lugerius
Perlero Nuevo

|
Registrado: 12 Jul 2008
Mensajes: 5
|
|
| Gracias, es exactamente lo que necesito |
|
|
Gracias, es exactamente lo que necesito, ahora voy a seguir agregando funciones a mi script, la solución que pusiste me despejó varias dudas que tenía con el hash y otras cosas, de todos modos creo que necesito un buen libro de Perl, apenas estoy descubriendo su potencia.
¡Saludos y muchas gracias!
Atte.
Luis G. Mendoza |
|
Powered by phpBB © 2001, 2005 phpBB Group
|