Lun Ene 21, 2008 6:52 am
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4130
Ubicación: Valladolid, España
|
|
|
|
|
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? |
|

Mie Ene 23, 2008 4:03 am
|
 |
chemaff
Perlero Nuevo

|
Registrado: 21 Ene 2008
Mensajes: 4
|
|
| Comparar ficheros de texto .csv por un campo clave |
|
|
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:
| Perl: | 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
} |
Gracias. |
|

Mie Ene 23, 2008 6:15 am
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4130
Ubicación: Valladolid, España
|
|
|
|
|
| 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? |
|
Mie Ene 23, 2008 6:03 pm
|
 |
Jenda
Perlero Frecuente

|
Registrado: 29 Oct 2007
Mensajes: 106
Ubicación: Praga, Republica Checa
|
|
|
|
|
Creo que necesitamos algunos ejemplos de lo que quieres.
Si tienes un fichero con
y otro con
¿son diferentes? Y si tienes
| Código: |
1;blah
2;blah
3;blah |
y en otro
| Código: |
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 |
|

Jue Ene 24, 2008 4:12 am
|
 |
chemaff
Perlero Nuevo

|
Registrado: 21 Ene 2008
Mensajes: 4
|
|
| Comparar ficheros de texto .csv por un campo clave |
|
|
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: |
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: |
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: |
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 |
|

Jue Ene 24, 2008 7:18 am
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4130
Ubicación: Valladolid, España
|
|
|
|
|
Ha quedado claro con el ejemplo: sacar las claves de UNO que no están en DOS.
Esta es una forma de hacerlo
| Perl: | #!/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'
}
|
Otra solución interesante sería usar el módulo List::Compare.
P.D. Esta solución es del foro Experto. |
|

Jue Ene 24, 2008 7:28 am
|
 |
danimera
Perlero Adicto

|
Registrado: 23 Jun 2005
Mensajes: 239
Ubicación: Colombia
|
|
|
|
|
mmmmmm Yo pasaría todo el fichero a un arreglo y lo compararía línea por línea. No sé si funcionará
| Perl: |
#!/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
}
|
Aunque también hice un módulo para trabajar con ficheros. Es sencillo pero tiene algunas funcionalidades interesantes ^^ |
|

Jue Ene 24, 2008 8:38 am
|
 |
chemaff
Perlero Nuevo

|
Registrado: 21 Ene 2008
Mensajes: 4
|
|
| comparar ficheros .csv por un campo clave |
|
|
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.  |
|
Powered by phpBB © 2001, 2005 phpBB Group
|