• Publicidad

Sumar distintos archivos

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

Sumar distintos archivos

Notapor R_Ortiz » 2010-04-26 06:49 @326

¡Buenas! Estoy realizando un script y me he atascado, a ver si me podéis echar una mano, os comento la situación.

Tengo una carpeta mensual que contiene 5 carpetas: semana1, semana2. semana3, semana4 y semana5. Cada carpeta contiene un archivo .csv con el mismo formato, con datos para cada semana. Lo que quiero hacer con mi script es crear un archivo csv que sea resultado de sumar el csv de cada semana. Lo que llevo hecho del script me recorre todas las carpetas y me lee los ficheros, lo que no sé cómo hacer es que me los vaya sumando. Esto es lo que llevo hecho:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3. print "¿Qué mes quieres sumar?";
  4. $mes=<STDIN>;
  5. chop($mes);
  6.  
  7. for(r=0;r<=4;$r++){
  8.        
  9. $fich = "C:/datos/$mes/semana$r/datos.csv";
  10. $fich2 = ">C:/datos/$mes/sumatorio.csv";
  11.  
  12. open (DATOS,$fich) || die "No pudo abrirse: $!";
  13. open (salida,$fich2) || die "No pudo abrirse: $!";
  14.  
  15. while (my $linea = <ENTRADA>) {
  16.    
  17.       my ($unidad, $medida1, $medida2, $medida3) = split(/;/, $linea);
  18.      
  19.     }
  20.    
  21.   }
  22.   close DATOS;
  23.   close salida;
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Quiero sumar lo que he llamado $medida1, $medida2, $medida3. La primera columna la dejo igual ya que es la descripción de la medida que estamos tomando.

¿Alguna idea sobre cómo ir sumando estas medidas que voy leyendo de los archivos y guardarlas en el archivo que he llamado salida?

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

Publicidad

Re: Sumar distintos archivos

Notapor explorer » 2010-04-26 07:01 @334

Solo tienes que crear unas variables que vayan guardando los totales, las vas actualizando, y, finalmente, mostrarlas (o guardarlas)

Queda así (no probado):
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use 5.010;
  5.  
  6. my ($total1, $total2, $total3);
  7.  
  8. print "¿Qué mes quieres sumar?";
  9. my $mes = <STDIN>;
  10. chop $mes;
  11.  
  12. for my $r (1..5) {
  13.     my $fichero_entrada = "C:/datos/$mes/semana$r/datos.csv";
  14.  
  15.     open my $DATOS, q[<], $fichero_entrada  or  die "No puedo abrirse $fichero_entrada: $!\n";
  16.  
  17.     while (my $linea = <$DATOS>) {
  18.         my (undef, $medida1, $medida2, $medida3) = split /;/, $linea;
  19.  
  20.         $total1 += $medida1;
  21.         $total2 += $medida2;
  22.         $total3 += $medida3;
  23.     }
  24.  
  25.     close $DATOS;
  26. }
  27.  
  28. my $fichero_salida = "C:/datos/$mes/sumatorio.csv";
  29. open my $SALIDA, q[>], $fichero_salida  or  die "No puedo escribir en $fichero_salida: $!\n";
  30. say     $SALIDA "$total1,$total2,$total3";
  31. close   $SALIDA;
  32.  
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: Sumar distintos archivos

Notapor R_Ortiz » 2010-04-26 09:15 @427

¡Muchas gracias otra vez, explorer!

Una cosa, esto lo que va haciendo es que me va sumando en la variables $medida1, por ejemplo, todos los valores de medida1 del mismo fichero, ¿no?

Me expresé mal antes, probablemente. Lo que quiero hacer es que $medida1 sea una suma de los 5 medida1 de los 5 ficheros.

Mejor pongo un ejemplo que se entiende mejor. Es igual para medida1, medida2 y medida3. Pongo un ejemplo con los archivos:

Semana1:
entrada.csv:

medida1 1 2 3
medida2 1 2 3
medida3 1 2 3
medida4 1 2 3

Semana2:
entrada.csv:

medida1 1 2 3
medida2 1 2 3
medida3 1 2 3
medida4 1 2 3

Semana3:
entrada.csv:

medida1 1 2 3
medida2 1 2 3
medida3 1 2 3
medida4 1 2 3

Semana4:
entrada.csv:

medida1 1 2 3
medida2 1 2 3
medida3 1 2 3
medida4 1 2 3

Semana5:
entrada.csv:

medida1 1 2 3
medida2 1 2 3
medida3 1 2 3
medida4 1 2 3

Salida.csv:

medida1 5 10 15
medida2 5 10 15
medida3 5 10 15
medida4 5 10 15

Lo he señalado por colores para que se vea más claro, sólo la primera fila, las otras serían la misma suma pero para la 2º fila, 3ª...

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

Re: Sumar distintos archivos

Notapor explorer » 2010-04-26 11:23 @516

Entonces, lo que debes hacer es:

* una vez leída la línea, desde el CSV, y separados los campos, identificar a qué medida corresponde

* Puedes usar un hash, usando las medidas como claves, y sus valores, un array anónimo, con tantos elementos como columnas restantes

* La suma sería algo así:
for my $j (1..$columnas) {
$medidas{$medida_id}[$j] += $medida[$j];
}

* Después de haber procesado todo los ficheros, solo queda recorrer las claves, de forma ordenada, de las %medidas, y por cada una de ellas, sacar las columnas, en una nueva fila CSV.
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: Sumar distintos archivos

Notapor R_Ortiz » 2010-04-26 13:11 @591

Perfecto, explorer, creo que lo he entendido. Me pongo con ello estos días y a ver qué tal... ¡Muchas gracias!
R_Ortiz
Perlero nuevo
Perlero nuevo
 
Mensajes: 16
Registrado: 2010-03-17 06:50 @326

Re: Sumar distintos archivos

Notapor R_Ortiz » 2010-04-28 06:09 @298

Bueno he intentado hacer lo que me comentaste pero creo que bastante regular. El final para ir sacando las claves no lo he entendido, no he trabajado apenas con hash y no tengo mucha idea...


Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3. print "¿Qué mes quieres sumar?";
  4. $mes=<STDIN>;
  5. chop($mes);
  6.  
  7. my %medidas;
  8.  
  9. for(r=0;r<=4;$r++){
  10.        
  11. $fich = "C:/datos/$mes/semana$r/datos.csv";
  12. $fich2 = ">C:/datos/$mes/sumatorio.csv";
  13.  
  14. open (DATOS,$fich) || die "No pudo abrirse: $!";
  15. open (salida,$fich2) || die "No pudo abrirse: $!";
  16.  
  17. while (my $linea = <ENTRADA>) {
  18.    
  19.       my ($unidad, $medida1, $medida2, $medida3) = split(/;/, $linea);
  20.      
  21.       my $medida1 = (split q[;])[1];
  22.       my $medida2 = (split q[;])[2];
  23.       my $medida3 = (split q[;])[3];
  24.      
  25.       $medidas{ $medida1 } = 1;
  26.       $medidas{ $medida2 } = 1;
  27.       $medidas{ $medida3 } = 1;
  28.      
  29.  for my $j (1..4){
  30.        
  31.         $medidas {$medida1}[$j]+=$medida1[$j];
  32.         $medidas {$medida2}[$j]+=$medida2[$j];
  33.         $medidas {$medida3}[$j]+=$medida3[$j];
  34.      
  35.     }
  36.  
  37.     }
  38.    
  39.   }
  40.   close DATOS;
  41.   close salida;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
R_Ortiz
Perlero nuevo
Perlero nuevo
 
Mensajes: 16
Registrado: 2010-03-17 06:50 @326

Re: Sumar distintos archivos

Notapor explorer » 2010-04-28 09:30 @438

Yo he elegido que la salida sea por orden alfabético:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use 5.010;
  5.  
  6. my %medidas;
  7.  
  8. print "¿Qué mes quieres sumar?";
  9. chomp (my $mes = <STDIN>);
  10.  
  11. for my $r (1..5) {
  12.     my $fichero_entrada = "$mes/semana$r/entrada.csv";
  13.  
  14.     open my $DATOS, q[<], $fichero_entrada  or  die "No puedo abrirse $fichero_entrada: $!\n";
  15.  
  16.     while (my $linea = <$DATOS>) {              # leemos la línea
  17.         my ($id, @datos) = split q[;], $linea;
  18.  
  19.         for my $c (0 .. $#datos) {              # sumamos las columnas
  20.             $medidas{$id}[$c] += $datos[$c];
  21.         }
  22.     }
  23.  
  24.     close $DATOS;
  25. }
  26.  
  27. my $fichero_salida = "sumatorio.csv";
  28.  
  29. open my $SALIDA, q[>], $fichero_salida  or  die "No puedo escribir en $fichero_salida: $!\n";
  30.  
  31. for my $id (sort keys %medidas) {               # salida ordenada
  32.     say $SALIDA join q[;], $id, @{$medidas{$id}};
  33. }
  34.  
  35. close   $SALIDA;
  36.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Y sí, aprender a usar los hash, array, hash de array, y otras estructuras complejas, ahorra bastante código.

Recuerda: Data::Dumper es tu amigo. Si agregas esto al final del programa:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use Data::Dumper;
  2. say Dumper \%medidas;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

sale
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
$VAR1 = {
          'medida1' => [
                         5,
                         10,
                         15
                       ],
          'medida3' => [
                         35,
                         40,
                         45
                       ],
          'medida4' => [
                         50,
                         55,
                         60
                       ],
          'medida2' => [
                         20,
                         25,
                         30
                       ]
        };
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
y así se ve la estructura que estás manejando.
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: Sumar distintos archivos

Notapor R_Ortiz » 2010-04-28 09:49 @451

Perfecto, ¡¡¡muchas gracias, explorer!!! Lo miraré estos días a ver qué tal...
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 30 invitados