• Publicidad

Comparar ficheros y actualizar en un tercero

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Comparar ficheros y actualizar en un tercero

Notapor R_Ortiz » 2010-04-16 06:14 @301

Bueno, os comento lo que estoy haciendo y el código que he hecho pero que no me hace nada... Tengo 2 ficheros .csv con unos cuantos campos. La idea es comparar los 2 ficheros y actualizar en un tercero los campos que aparezcan nuevos. Me explico:

Tendríamos como fichero de entrada1:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
campo1;campo2;campo3;campo4;campo5
campo6;campo7;campo8;campo9;campo10
campo11;campo12;campo13;campo14;campo15
campo16;campo17;campo18;campo19;campo20
campo21;campo22;campo23;campo24;campo25
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Y queremos comparar los campos de la segunda columna con otro fichero que pongo a continuación, que está en el mismo formato, y si detecta un campo de la segunda columna que no esté en el fichero entrada1 pues lo metemos en un tercer fichero acompañado de todos los campos también de su fila.

El fichero que le vamos a pasar para ver si hay actualizaciones sería este fichero:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
campo1;campo2;campo3;campo4;campo5
campo6;campo7;campo8;campo9;campo10
campo11;campo12;campo13;campo14;campo15
campoN;campoN;campoN;campoN;campoN
campo16;campo17;campo18;campo19;campo20
campo21;campo22;campo23;campo24;campo25
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Como veis, en este último fichero tenemos los mismos campos pero se nos ha actualizado un campoN. Aunque ponga en todas las columnas campoN, el único que quiero comparar es el de la segunda columna, y como detecta que es campoN que no estaba en el otro fichero pues lo coge junto a todos los campos de su fila. Es decir, nos quedaría en el tercer fichero:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
campoN;campoN;campoN;campoN;campoN
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Es lo que he intentado hacer en el siguiente código pero creo que con bastantes fallos:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3.   my $entrada1="C:/Pruebas/CamposTotales.csv";
  4.   my $entrada2="C:/Pruebas/CamposActualizar.csv";
  5.   my $salida ="C:/Agilent/Celdas/CamposNuevos.csv";
  6.  
  7.   open (ENTRADA1,"$entrada1") || die "ERROR: No puedo abrir el fichero $entrada\n";
  8.   open (ENTRADA2,"$entrada2") || die "ERROR: No puedo abrir el fichero $salida\n";
  9.   open (SALIDA,">$salida") || die "ERROR: No puedo abrir el fichero $salida\n";
  10.  
  11.    while (my $linea = <ENTRADA1>) {
  12.    
  13.         my ($campo1, $campo2, $campo3, $campo4, $campo5) = split(/;/, $linea);
  14.             }
  15.      
  16. while (my $linea = <ENTRADA2>) {
  17.    
  18.         my ($campo21, $campo22, $campo23, $campo24, $campo25) = split(/;/, $linea);
  19.                
  20.      }
  21.   if (campo2!=campo22){
  22.  
  23.   print SALIDA  "$campo21, $campo22, $campo23, $campo24, $campo25\n";
  24.    
  25.   }
  26.  
  27.   close (ENTRADA1);
  28.   close (ENTRADA2);
  29.   close (SALIDA);
  30.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


A ver si me podéis echar una mano. ¡¡Muchas gracias!!
Última edición por R_Ortiz el 2010-04-16 10:22 @474, editado 1 vez en total
R_Ortiz
Perlero nuevo
Perlero nuevo
 
Mensajes: 16
Registrado: 2010-03-17 06:50 @326

Publicidad

Re: Comparar ficheros y actualizar en un tercero

Notapor explorer » 2010-04-16 06:51 @327

Una opción sería leer todo el primer fichero, quedarnos con los campos de la segunda columna, y luego, leer el segundo fichero línea a línea, y si es un registro nuevo, lo sacamos.

Como es costumbre, cuando se trata de recordar cosas, lo normal, es usar un hash (diccionario).

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4.  
  5. my %campo;
  6.  
  7. # Leemos el primer fichero
  8. open my $FICHERO1, q[<], 'fichero1.csv';
  9.  
  10. while (<$FICHERO1>) {
  11.     my $segunda_columna = (split q[;])[1];
  12.  
  13.     $campo{ $segunda_columna } = 1;
  14. }
  15.  
  16.  
  17. # Abrimos el tercer fichero, para salida
  18. open my $SALIDA, q[>], 'salida.txt';
  19.  
  20.  
  21. # Leemos el segundo fichero
  22. open my $FICHERO2, q[<], 'fichero2.csv';
  23.  
  24. while (<$FICHERO2>) {
  25.     my $segunda_columna = (split q[;])[1];
  26.  
  27.     if ( ! $campo{ $segunda_columna } ) {   # Si no es un campo visto antes
  28.         print $SALIDA $_;                   # Imprimimos toda la línea
  29.     }
  30. }
  31.  
  32.  
  33. # Cerramos ficheros
  34. close $FICHERO1;
  35. close $FICHERO2;
  36. close $SALIDA;
  37.  
  38. __END__
  39.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
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

Re: Comparar ficheros y actualizar en un tercero

Notapor R_Ortiz » 2010-04-16 10:34 @482

¡Muchas gracias, explorer!

No lo he probado todavía porque no lo tengo en el ordenador en el que trabajo con Perl. Una preguntilla: el fichero 2 que es el que tiene los campos para actualizar, perfecto, entiendo lo que haces que cuando coge una variable que no ha leído la mete en el fichero de salida. Pero quiero que además de esa variable, que es la segunda columna, se meta las otras 4 columnas. ¿Cómo lo haría, en el segundo fichero además de leer la segunda columna leo todas las demás y luego las escribo?

¡Gracias!
R_Ortiz
Perlero nuevo
Perlero nuevo
 
Mensajes: 16
Registrado: 2010-03-17 06:50 @326

Re: Comparar ficheros y actualizar en un tercero

Notapor explorer » 2010-04-16 17:40 @778

Fíjate bien en la línea 28...
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

Re: Comparar ficheros y actualizar en un tercero

Notapor R_Ortiz » 2010-04-17 10:10 @465

Perdona, jeje... ¡Gracias!
R_Ortiz
Perlero nuevo
Perlero nuevo
 
Mensajes: 16
Registrado: 2010-03-17 06:50 @326

Re: Comparar ficheros y actualizar en un tercero

Notapor R_Ortiz » 2010-04-19 09:05 @420

Un pregunta, explorer: ¿cuál es el motivo de poner?

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
use strict;
use warnings;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Es que me estaba dando problemas el código al integrarlo en un script con más cosas y demás y me daba fallo al reconocer una variable y era problema de eso ya que lo he comentado y se me ha ejecutado correctamente...
R_Ortiz
Perlero nuevo
Perlero nuevo
 
Mensajes: 16
Registrado: 2010-03-17 06:50 @326

Re: Comparar ficheros y actualizar en un tercero

Notapor explorer » 2010-04-19 10:21 @473

* use strict; Nos comprometemos a que a partir de esta línea vamos a programar de forma "estricta" (generar un error en tiempo de compilación si usamos referencias simbólicas, generar un error en tiempo de compilación si estamos usando variables que no han sido declaradas antes, y generar un error en tiempo de compilación si estamos usando una palabra suelta como si fuera una llamada a una función)

* use warnings; muestra avisos de cualquier cosa sospechosa de ser un error de programación (entre otras cosas).

El primero te obligará a programar de forma "correcta". En lugar de hacer programas así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. $dimension = 'radio';      # variables no declaradas en ningún sitio
  3. $pi = 3.1416;
  4. $$dimension = 12;          # referencia simbólica $radio
  5. $unidad = centimetros;     # palabra suelta
  6.  
  7. $circunferencia = 2 * $radio * $pi;
  8.  
  9. print "La circunferencia tiene $circunferencia $unidad\n";
  10. __END__
  11. La circunferencia tiene 75.3984 centimetros
  12.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

nos obliga a escribirlos así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4.  
  5. my $radio  = 12;
  6. my $pi     = 3.1416;
  7. my $unidad = 'centimetros';
  8.  
  9. my $circunferencia = 2 * $radio * $pi;
  10.  
  11. print "La circunferencia tiene $circunferencia $unidad\n";
  12.  
  13. __END__
  14.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Como ves, nos vemos obligados a declarar todas nuestras variables con my(), para indicar que todas ellas van a ser locales a nuestro programa (no van a ser conocidas fuera de él). Y nada de referencias simbólicas o usar palabras sueltas.

Seguro que el fallo que te sale es porque estás usando variables sin declararlas con my().

Esto, tiene una enorme ventaja cuando estás empezando a programar en Perl, porque perl te va a avisar de cada variable nueva que él encuentre y no hayas declarado: de esa manera localizarás inmediatamente errores de programación por fallos en la escritura. Ejemplo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4.  
  5. my $radio  = 12;
  6. my $pi     = 3.1416;
  7. my $unidad = 'centimetros';
  8.  
  9. my $circunferencia = 2 * $radio * $pi;
  10.  
  11. print "La circunferencia tiene $circunfrencia $unidad\n";
  12.  
  13. __END__
  14. Global symbol "$circunfrencia" requires explicit package name at ./kk.pl line 11.
  15. Execution of ./kk.pl aborted due to compilation errors.
  16.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Si no tuvieras el 'strict' puesto, perl no daría ningún error (Perl es un lenguaje muy liberal y, si no le advertimos, admitirá muchos engendros que escribamos), pero no saldría lo que querríamos.

Si en vez de 'strict' estuviera puesto solo 'warnings', perl nos informará de esta manera:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Name "main::circunfrencia" used only once: possible typo at ./kk.pl line 11.
Use of uninitialized value in concatenation (.) or string at ./kk.pl line 11.
La circunferencia tiene  centimetros
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
que es decir: "he encontrado algo raro, pero aún así, lo he ejecutado".

El uso de los dos es una buena manera de aprender a programar Perl, y además, saber que tenemos la tranquilidad de que el propio perl nos informará de los errores de programación (al menos, los referidos a fallos de escritura).

Yo, particularmente, desde que uso Perl v5.10, uso el módulo common::sense, que activa estos y otros controles, para conseguir y obligarte a escribir programas Perl muy legibles.
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

Re: Comparar ficheros y actualizar en un tercero

Notapor R_Ortiz » 2010-04-19 13:28 @603

Perfectamente aclarado. ¡Muchas gracias!
R_Ortiz
Perlero nuevo
Perlero nuevo
 
Mensajes: 16
Registrado: 2010-03-17 06:50 @326


Volver a Básico

¿Quién está conectado?

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