Comparar líneas en archivos de texto
Publicado: 2015-09-30 11:56 @539
Buenas tardes.
Tengo que comparar un par de archivos de texto con la siguiente estructura:
En el archivo nuevo puede haber cambiado la edad o dirección de algún registro, por lo que en el resultado debo guardar tanto la línea del archivo viejo como la del nuevo. Si no ha cambiado nada, no guardo nada en el resultado.
La estrategia que he seguido es la siguiente:
El problema es que los archivos que estoy comparando tienen sobre 2000 líneas y he visto que hay "alias" que, a pesar de estar en el archivo intermedio "Diferencias.txt" han desaparecido en el archivo de resultados. Y algún "alias" que, a pesar de existir una sola vez en el archivo "Diferencias.txt", aparece duplicado en el resultado.
Como no tengo mucha experiencia con Perl, seguro que he metido la pata en algo. ¿Alguna sugerencia? Os dejo aquí el código empleado, por si a alguien le puede servir. Gracias de antemano.
Tengo que comparar un par de archivos de texto con la siguiente estructura:
Using text Syntax Highlighting
Sexo;Estado;DNI;Nombre;Edad;Alias;Altura;Direccion;Hijos;Observaciones
Hombre;Soltero;11111111;Jose Aja Aja;50;pepe;2.00;calle 1;;Rubio
Mujer;Casada;22222222;Ana Aja Aje;65;anita;1.80;calle 3;2;Rubia
Mujer;Divorciada;33333333;Laura Asi Asa;38;laurita;1.70;calle 4;1;
Hombre;Soltero;11111111;Jose Aja Aja;50;pepe;2.00;calle 1;;Rubio
Mujer;Casada;22222222;Ana Aja Aje;65;anita;1.80;calle 3;2;Rubia
Mujer;Divorciada;33333333;Laura Asi Asa;38;laurita;1.70;calle 4;1;
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
En el archivo nuevo puede haber cambiado la edad o dirección de algún registro, por lo que en el resultado debo guardar tanto la línea del archivo viejo como la del nuevo. Si no ha cambiado nada, no guardo nada en el resultado.
La estrategia que he seguido es la siguiente:
- leo el archivo viejo y lo meto en un hash
- abro el archivo nuevo y, para cada línea, veo si existe la clave en el hash anterior
- Si existe la clave, no guardo nada
- Si no existe, guardo la línea en un archivo intermedio llamado "Diferencias.txt"
- una vez tengo el archivo de diferencias completado, lo vuelvo a abrir y, para cada línea, leo un valor que no se repite, que es el "alias"
- abro el archivo viejo, busco la línea que contiene ese alias y la guardo en el resultado final "Comparado.txt" con el indicador "Archivo viejo" al inicio de la línea
- abro el archivo nuevo, busco la línea que contiene ese alias y la guardo en el resultado final "Comparado.txt" con el indicador "Archivo nuevo" al inicio de la línea.
El problema es que los archivos que estoy comparando tienen sobre 2000 líneas y he visto que hay "alias" que, a pesar de estar en el archivo intermedio "Diferencias.txt" han desaparecido en el archivo de resultados. Y algún "alias" que, a pesar de existir una sola vez en el archivo "Diferencias.txt", aparece duplicado en el resultado.
Como no tengo mucha experiencia con Perl, seguro que he metido la pata en algo. ¿Alguna sugerencia? Os dejo aquí el código empleado, por si a alguien le puede servir. Gracias de antemano.
Using perl Syntax Highlighting
- #!/usr/bin/perl
- use strict; # estilo estricto
- use warnings; # activar advertencias
- use diagnostics; # diagnósticos de fallos
- use autodie; # «Es mejor morir que regresar con deshonor» --proverbio Klingon
- system("cls");
- print "Buscamos diferencias entre dos ficheros txt.\n";
- print "Fichero Antiguo(sin extension): ";
- my $f1 = <>;
- chomp($f1);
- print "Fichero Nuevo(sin extension): ";
- my $f2 = <>;
- chomp($f2);
- my $ruta1 = "C:\\Documents and Settings\\Admin\\My Documents\\Perl\\Pruebas\\$f1\\";
- my $ruta2 = "C:\\Documents and Settings\\Admin\\My Documents\\Perl\\Pruebas\\$f2\\";
- open my $afile, '<', $ruta1 . $f1 . "_limpio.txt"
- or die "Couldn't open $f1.txt: $!";
- my %a_lineas;
- while ( my $linea1 = <$afile> ) {
- chomp $linea1;
- $a_lineas{$linea1} = 1;
- }
- open my $SALIDA1, '>', $ruta2 . "Diferencias_" . $f1 . "_" . $f2 . ".txt"; # Escritura del archivo intermedio
- open my $bfile, '<', $ruta2 . $f2 . "_limpio.txt"
- or die "Couldn't open $f2.txt: $!";
- while ( my $linea2 = <$bfile> ) {
- chomp $linea2;
- if ( exists $a_lineas{$linea2} ) {
- next;
- }
- else {
- print $SALIDA1 $linea2 . "\n";
- }
- }
- close $SALIDA1;
- close $afile;
- close $bfile;
- open my $diffile, '<', $ruta2 . "Diferencias_" . $f1 . "_" . $f2 . ".txt";
- open my $SALIDA2, '>', $ruta2 . "Comparado_" . $f1 . "_" . $f2 . ".txt";
- while ( my $linea3 = <$diffile> ) {
- chomp $linea3;
- my (@campos) = split ";", $linea3, 8;
- my $alias = $campos[5];
- open my $cfile, '<', $ruta1 . $f1 . "_limpio.txt"
- or die "Couldn't open $f1.txt: $!";
- while ( my $linea4 = <$cfile> ) {
- chomp $linea4;
- if ( $linea4 =~ /$alias/ ) {
- print $SALIDA2 "Fichero viejo;" . $linea4 . "\n"; # Escritura del fichero Resultados.
- last;
- }
- }
- close $cfile;
- open my $dfile, '<', $ruta2 . $f2 . "_limpio.txt"
- or die "Couldn't open $f2.txt: $!";
- while ( my $linea5 = <$dfile> ) {
- chomp $linea5;
- if ( $linea5 =~ /$alias/ ) {
- print $SALIDA2 "Fichero nuevo;" . $linea5 . "\n"; # Escritura del fichero Resultados.
- last;
- }
- }
- close $dfile;
- }
- close $diffile;
- close $SALIDA2;
Coloreado en 0.005 segundos, usando GeSHi 1.0.8.4