• Publicidad

Comparar ficheros en base a un mismo campo clave

Así que programas sin strict y las expresiones regulares son otro modo de hablar. Aquí encontrarás respuestas de nivel avanzado, no recomendable para los débiles de corazón.

Comparar ficheros en base a un mismo campo clave

Notapor chemaff » 2008-01-21 06:55 @329

Hola,
necesito ayuda sobre cómo comparar 2 ficheros. Ambos ficheros tienen un campo clave en común y necesito crear un fichero de salida con la diferencias entre ambos solo si no coincide este campo clave.

Si alguien me puede marcar unas líneas muy generales creo que yo podré acabar solo el programa.

No sé si aquí, en Experto, es el lugar adecuado.

Creo que no me sirve:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
use File::Compare;    if (compare("file1","file2") == 0) ...
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4


Muchas Gracias
chemaff
Perlero nuevo
Perlero nuevo
 
Mensajes: 4
Registrado: 2008-01-21 06:47 @324

Publicidad

Notapor explorer » 2008-01-21 07:52 @369

No nos has dicho el formato de esos ficheros. ¿Son de texto?
Tampoco como se organizan los datos y la clave. ¿Están separados/colocados de alguna manera?
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Comparar ficheros de texto .csv por un campo clave

Notapor chemaff » 2008-01-23 05:03 @252

Hola,

Tienes razón me dejado algunos datos importantes.
Son dos ficheros de texto en formato .csv, delimitados por ";".
La clave es alfanumérica.

De momento he encontrado una solución aunque no sé si es la mejor; tal vez Perl permita una manera mejor y mas rápida de hacerlo.

La solución que estoy desarrollando (aún no lo he terminado) es hacer 2 bucles while anidados, en cada bucle recorro un fichero y en el while más adentro al llegar al final de fichero vuelvo a ponerlo al principio con un seek fichero,0,0.

Más o menos es esto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
open (CL_UNO,"<CL_UNO.csv") ;
open (CL_DOS, "<CL_DOS.csv")  ;

open (CL_RESULTADO,">>CL_RESULTADO.csv")  ;

while($linUno = <CL_UNO>) {
   chop($linUno);      
   @alinUno=split(";",$linUno);
     
   while($linDos = <CL_DOS>) {
      chop($linDos);
          @alinDos=split(";",$linDos);

       if  if ( $alinUno[0]  != $alinDos[0] )   {  
       print CL_RESULTADO "$linUno \n" ;      }
   }
   seek CL_DOS, 0, 0    ## ir la principio del fichero
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Gracias.
chemaff
Perlero nuevo
Perlero nuevo
 
Mensajes: 4
Registrado: 2008-01-21 06:47 @324

Notapor explorer » 2008-01-23 07:15 @344

Es decir... si el primer fichero tiene, por ejemplo 12 claves distintas y el segundo fichero tiene otras 12 claves distintas y distintas también del primero, ¿debe generar 144 print?
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor Jenda » 2008-01-23 19:03 @835

Creo que necesitamos algunos ejemplos de lo que quieres.

Si tienes un fichero con
Código: Seleccionar todo
1;blah
2;blah

y otro con
Código: Seleccionar todo
2;blah
1;blah

¿son diferentes? Y si tienes
Código: Seleccionar todo
1;blah
2;blah
3;blah

y en otro
Código: Seleccionar todo
1;blah
4;blah
2;blah
3;blah

¿quieres que el script imprima solo que hay una clave nueva o quieres que imprima tres veces que las líneas son diferentes? ¿O algo completamente diferente?

Jenda
Jenda
Perlero nuevo
Perlero nuevo
 
Mensajes: 132
Registrado: 2007-10-29 06:31 @313
Ubicación: Praga, Republica Checa

Comparar ficheros de texto .csv por un campo clave

Notapor chemaff » 2008-01-24 05:12 @258

Siempre comparo el fichero UNO con el fichero DOS y me interesa guardar en un fichero nuevo de salida el registro/linea que tenemos en UNO y que no tenemos en fichero DOS.
Puede que mas adelante necesite hacerlo al revés (comparar fichero DOS con UNO) pero de momento no lo necesito.

Por ejemplo si el fichero UNO tiene
Código: Seleccionar todo
A1;aaaaaaaa;10;hgjgjkhgk;
A2;aaaabahdhdhdhd;11;hGJHGJH;
A3;tuytuytu;20;yyuLJLKjl_kiui;
B1;wwwwww;21;6876876;
C3;zzzzzzzzzzzzzzzzzzzz;50;40;rerhgHGFH787;


El fichero DOS tiene
Código: Seleccionar todo
A1;aaaaaaaa;7000;TTTTTTTTTTT;QQQQQQQQQQQQ;1000;
A2;bbbbnnnHtht;600;WWWWWWW;ASASASASA;1001;
B1;TYTYTYTYT;170;NNNNNNNNNNN;VBVBVBVBVB;1002;


La clave es el 1er campo: A1, A2, A3, B1 y C3.

Según este ejemplo el fichero de salida debe tener sólo:
Código: Seleccionar todo
A3;tuytuytu;20;yyuLJLKjl_kiui;
C3;zzzzzzzzzzzzzzzzzzzz;50;40;rerhgHGFH787;

Por que ambos no están en fichero DOS.

No sé si me he explicado bien.

Muchas Gracias por vuestra ayuda
chemaff
Perlero nuevo
Perlero nuevo
 
Mensajes: 4
Registrado: 2008-01-21 06:47 @324

Notapor explorer » 2008-01-24 08:18 @388

Ha quedado claro con el ejemplo: sacar las claves de UNO que no están en DOS.

Esta es una forma de hacerlo

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl

# Leemos ficheros y lo pasamos a hash,
# siendo la clave el primer campo de la línea
my %uno = map { (split q{;})[0] => $_ } do { open F, "<uno"; <F> };
my %dos = map { (split q{;})[0] => $_ } do { open F, "<dos"; <F> };

# Sacamos las diferencias entre los dos
foreach my $uno ( keys %uno ) {
    print $uno{$uno}                    # Saca la línea de 'uno'
        if not $dos{$uno};              #    si no existe esa clave en 'dos'
}

 
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Otra solución interesante sería usar el módulo List::Compare.

P.D. Esta solución es del foro Experto.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor danimera » 2008-01-24 08:28 @394

mmmmmm Yo pasaría todo el fichero a un arreglo y lo compararía línea por línea. No sé si funcionará

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl

#Abrimos los ficheros

open (DATABASE, "<$fichero1") || &error('abrir','archivo');
flock (DATABASE,1)||&error('lock','file');
@registros1 = <DATABASE>;
close (DATABASE) || &error('cerrar','archivo');

open (DATABASE, "<$fichero2") || &error('abrir','archivo');
flock (DATABASE,1)||&error('lock','file');
@registros2 = <DATABASE>;
close (DATABASE) || &error('cerrar','archivo');

foreach $a(@resgistros1){

     foreach $b(@resgistros2)  print $_ if $a eq b; # caturo los que son iguales
}

 
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Aunque también hice un módulo para trabajar con ficheros. Es sencillo pero tiene algunas funcionalidades interesantes ^^
100% Telch - Perl Web Programming
Cali PerlMongers: http://cali.pm.org
Avatar de Usuario
danimera
Perlero frecuente
Perlero frecuente
 
Mensajes: 871
Registrado: 2005-06-23 19:02 @834
Ubicación: Colombia

comparar ficheros .csv por un campo clave

Notapor chemaff » 2008-01-24 09:38 @443

Muchas Gracias por las soluciones.
Había encontrado una solución por mi mismo pero es "un poco" más larga.
Probaré estas soluciones, espero entenderlas, en especial la de Explorer, está más allá de mis conocimientos actuales de Perl.

Muchas gracias. :D
chemaff
Perlero nuevo
Perlero nuevo
 
Mensajes: 4
Registrado: 2008-01-21 06:47 @324


Volver a Avanzado

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 0 invitados