• Publicidad

Cómo agrupar registros de un fichero

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

Cómo agrupar registros de un fichero

Notapor teco000 » 2008-06-24 18:19 @804

Saludos, me pueden ayudar, estoy recorriendo un archivo, del cual tengo que sacar un resumen, no sé si existe alguna función, o lo tengo que meter a una matriz, les mando un ejemplo de como está el fichero:

Líneas que trae el archivo:
Código: Seleccionar todo
49204032   00000    45.40    20080505
49204032   00000    45.40    20080505
49204032   20000    45.40    20080505
49204032   20000    45.40    20080505
49204032   20000    45.40    20080505
49204030   00000    45.40    20080505
49204030   00000    45.40    20080505
49204030   00000    45.40    20080505
49204031   10000    45.40    20080505
49204031   20000    45.40    20080505
49204031   10000    45.40    20080505
Resumen: tiene que quedar así
Código: Seleccionar todo
49204032   00000     90.80   2
49204032   20000    136.20   3
49204030   00000    136.20   3
49204031   10000     90.80   2
49204031   20000     45.40   2
teco000
Perlero nuevo
Perlero nuevo
 
Mensajes: 67
Registrado: 2008-05-29 15:22 @682
Ubicación: Guatemala

Publicidad

Notapor explorer » 2008-06-25 04:36 @233

¿Es importante el orden de salida de las líneas?

Para agrupar líneas, lo mejor es usar los hash, aunque también se puede hacer leyendo línea a línea:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
        1 #!/usr/bin/perl
        2
        3 $total  = 0;
        4 $numero = 0;
        5 $anterior_codigo = '';
        6
        7 sub pinta_resumen {
        8     print  "$anterior_codigo";
        9     printf "%10.2f%4d\n", $total, $numero;
       10 }
       11
       12 foreach ( sort <DATA> ) {
       13
       14     ( $codigo1, $codigo2, $cantidad ) = split;
       15     $codigo = "$codigo1   $codigo2";
       16
       17     if ( $codigo ne $anterior_codigo ) {
       18         if ( $anterior_codigo ) {
       19             pinta_resumen;
       20             $total = $numero = 0;
       21         }
       22         $anterior_codigo = $codigo;
       23     }
       24     $total += $cantidad;
       25     $numero++;
       26 }
       27 pinta_resumen;
       28
       29
       30 __DATA__
       31 49204032   00000    45.40    20080505
       32 49204032   00000    45.40    20080505
       33 49204032   20000    45.40    20080505
       34 49204032   20000    45.40    20080505
       35 49204032   20000    45.40    20080505
       36 49204030   00000    45.40    20080505
       37 49204030   00000    45.40    20080505
       38 49204030   00000    45.40    20080505
       39 49204031   10000    45.40    20080505
       40 49204031   20000    45.40    20080505
       41 49204031   10000    45.40    20080505
 
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
Código: Seleccionar todo
49204030   00000    136.20   3
49204031   10000     90.80   2
49204031   20000     45.40   1
49204032   00000     90.80   2
49204032   20000    136.20   3
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 kidd » 2008-06-25 08:11 @383

Veamos, aquí mi intento usando hash.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my @DATA = (
'49204032   00000    45.40    20080505',
'49204032   00000    45.40    20080505',
'49204032   20000    45.40    20080505',
'49204032   20000    45.40    20080505',
'49204032   20000    45.40    20080505',
'49204030   00000    45.40    20080505',
'49204030   00000    45.40    20080505',
'49204030   00000    45.40    20080505',
'49204031   10000    45.40    20080505',
'49204031   20000    45.40    20080505',
'49204031   10000    45.40    20080505',
);


my %Data;

for my $data ( @DATA ) {

    my ($cod1, $cod2, $count) = split /\s+/, $data;

    my $key = $cod1." ".$cod2;

    if( $Data{$key} ){
        $Data{$key}[0] += $count;
        $Data{$key}[1]++;
    }
    else{
        $Data{$key} = [$count,1];
    }

}


for my $key( sort keys %Data ){
    print $key;
    printf "%10.2f%4d\n", $Data{$key}[0], $Data{$key}[1];

}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Uriel Lizama Perl programmer fundador de Perl en Español
Perl Programming Language
Avatar de Usuario
kidd
Creador de Perl en Español
Creador de Perl en Español
 
Mensajes: 1166
Registrado: 2003-10-15 16:52 @744
Ubicación: México

Notapor teco000 » 2008-06-25 10:11 @466

Gracias a los dos, ambas respuestas me son muy útiles. :D
teco000
Perlero nuevo
Perlero nuevo
 
Mensajes: 67
Registrado: 2008-05-29 15:22 @682
Ubicación: Guatemala

Notapor explorer » 2008-06-25 10:59 @499

Esta es mi solución usando arrays:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl

while ( <DATA> ) {
    ( $codigo1, $codigo2, $cantidad ) = split;
    $tabla[$codigo1][$codigo2][0] += $cantidad;
    $tabla[$codigo1][$codigo2][1] ++;
}
for $x ( 0 .. $#tabla ) {
    next if !exists $tabla[$x];
    for $y ( 0 .. $#{$tabla[$x]} ) {
        next if !exists $tabla[$x][$y];
        printf "%s   %05d%10.2f%4d\n", $x, $y, $tabla[$x][$y][0], $tabla[$x][$y][1];
    }
}
__DATA__
49204032   00000    45.40    20080505
49204032   00000    45.40    20080505
49204032   20000    45.40    20080505
49204032   20000    45.40    20080505
49204032   20000    45.40    20080505
49204030   00000    45.40    20080505
49204030   00000    45.40    20080505
49204030   00000    45.40    20080505
49204031   10000    45.40    20080505
49204031   20000    45.40    20080505
49204031   10000    45.40    20080505
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
aunque... es mejor no abusar de este tipo de engendros...
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 teco000 » 2008-06-25 17:18 @763

Saludos, tengo otro problema, con el siguiente código lo meto a un array:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
if ($bin == 5555555545){
    $acumtrama = "$acumtrama$bin $codtrans $valor\n";
    @DATA = "$acumtrama";
    $conteo_B++;
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

que me da este resultado al momento de ver el array,
Código: Seleccionar todo
49204032   00000    45.40    20080505
49204032   00000    45.40    20080505
49204032   20000    45.40    20080505
49204032   20000    45.40    20080505
49204032   20000    45.40    20080505
49204030   00000    45.40    20080505
49204030   00000    45.40    20080505
49204030   00000    45.40    20080505
49204031   10000    45.40    20080505
49204031   20000    45.40    20080505
49204031   10000    45.40    20080505


Luego aplico la solución que me dieron pero no me agarra el array como espero.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
sub pinta_resumen {
       print  "$anterior_codigo";
       printf "%10.2f%4d\n", $total, $numero;
        }
foreach ( sort <@DATA> ) {
      ( $codigo1, $codigo2, $cantidad ) = split;
      $codigo = "$codigo1   $codigo2";
            if ( $codigo ne $anterior_codigo ) {
               if ( $anterior_codigo ) {
                   pinta_resumen;
                    $total = $numero = 0;
                }
                $anterior_codigo = $codigo;
            }
            $total += $cantidad;
            $numero++;
        }
        pinta_resumen;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
teco000
Perlero nuevo
Perlero nuevo
 
Mensajes: 67
Registrado: 2008-05-29 15:22 @682
Ubicación: Guatemala

Notapor explorer » 2008-06-25 17:41 @778

Con
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
@DATA = "$acumtrama";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

no guardas nada en el array, solo un elemento.

Debes usar push():
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
push @DATA, $acumtrama;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

O mejor:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
if ($bin eq 5555555545){
    push @DATA, "$bin $codtrans $valor";
    $conteo_B++;
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Y luego, hacer el bucle por @DATA:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
foreach ( @DATA )  {
Coloreado en 0.001 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

Notapor teco000 » 2008-06-25 18:22 @807

Gracias, ese era mi gran error. Ya funciona
teco000
Perlero nuevo
Perlero nuevo
 
Mensajes: 67
Registrado: 2008-05-29 15:22 @682
Ubicación: Guatemala

Re: Cómo agrupar registros de un fichero

Notapor agutier » 2009-09-09 11:17 @511

teco000 escribiste:Saludos, me pueden ayudar, estoy recorriendo un archivo, del cual tengo que sacar un resumen, no sé si existe alguna función, o lo tengo que meter a una matriz, les mando un ejemplo de como está el fichero:

Líneas que trae el archivo:
Código: Seleccionar todo
49204032   00000    45.40    20080505
49204032   00000    45.40    20080505
49204032   20000    45.40    20080505
49204032   20000    45.40    20080505
49204032   20000    45.40    20080505
49204030   00000    45.40    20080505
49204030   00000    45.40    20080505
49204030   00000    45.40    20080505
49204031   10000    45.40    20080505
49204031   20000    45.40    20080505
49204031   10000    45.40    20080505
Resumen: tiene que quedar así
Código: Seleccionar todo
49204032   00000     90.80   2
49204032   20000    136.20   3
49204030   00000    136.20   3
49204031   10000     90.80   2
49204031   20000     45.40   2


Esto mismo me sucede pero el lio es que recibo 200 archivo de 50000 lineas la estructura de registro de cada archivo es el mismo y necesito generar al final del dia un resumen en un solo archivo de todos los archivos procesados. en este momento lo estoy haciendo en awk pero me gustaria hacerlo con perl.
Última edición por agutier el 2009-09-09 11:29 @520, editado 1 vez en total
agutier
Perlero nuevo
Perlero nuevo
 
Mensajes: 1
Registrado: 2008-12-09 18:38 @818

Re: Cómo agrupar registros de un fichero

Notapor explorer » 2009-09-09 11:23 @516

Bienvenido a los foros de Perl en Español, agutier.

Pasar de awk a Perl es 'casi' trivial. Si podemos ayudarte, pues aquí estaremos.

Puedes empezar por estudiar algunas de las soluciones comentadas antes. Luego, probar a escribir algo de código. Si te atascas, lo publicas por aquí y te ayudamos.
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


Volver a Básico

¿Quién está conectado?

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