• Publicidad

Contando líneas repetidas

¿Ya sabes lo que es una referencia? Has progresado, el nível básico es cosa del pasado y ahora estás listo para el siguiente nivel.

Contando líneas repetidas

Notapor novato_aprendiendo » 2008-07-30 20:42 @904

Buenasss... bueno este es mi primer post, y la verdad es que desde que encontré este foro (casi por error) no dejo se sorprenderme de lo amables y serviciales que son los socios del mismo.
Bueno.. les comento mi problema.

Tengo que parsear unos logs del Apache, la parte de expresiones regulares la aprendí googleando y de algunos tutoriales.
Resulta que en mi script de Perl hago casi todas las cosas que necesito. Mi script recibe como parámetro un log y de ese log busca keys para generar un "archivotemporal" . Ese archivo tiene la siguiente estructura:

Código: Seleccionar todo
20080723 221746 260 433 miweb.com
20080723 220049 260 433 lacasa.com
20080723 132219 300 500 yo.com
20080723 175419 300 500 sss2.com
20080723 214433 260 433 yodenuevo.com
20080723 221835 300 500 unknown
20080723 208982 260 433 tagged.com
20080723 49084 260 433 myspace.com


Todos separados por un espacio.

Donde:
* el primer campo es la fecha 2008 -07 -23
* el segundo es el ID del usuario
* el tercero y cuarto son el tamaño de su foto
* y el quinto es la web personal.

A ese "archivotemporal" lo vuelvo a parsear dentro de mi script con una función que me cuenta las veces que se repite cada línea (ordenadas). La función es la siguiente:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
sub count_lines($$)
{
    my $filename = shift;
    my $outputfile = shift;
    %seen = ();
    open(INPUT,$filename) || die("Could not open input file stage 2");
    open(OUTPUT,"> $outputfile") || die("Could not open output file stage 2");
    while(<INPUT>)
        {
            while (/^(.*)$/g)
                {
                    $seen{ lc $1 }++;
                }
        }
    foreach $line ( sort { $seen{$b} <=> $seen{$a} } keys %seen )
        {
            print OUTPUT "$line $seen{$line}\n";
        }
    close(INPUT);
    close(OUTPUT);
}
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Pero resulta que esa función en algún momento de su ejecución me escribe en OUTPUT cualquier cosa... pero cualquier cosa.
Ejemplo:

Código: Seleccionar todo
20080723 97782 260 433 msappspace.com 1
20080723 192535 260 433 tagged.com 1
20080723 116064 300 500 hi5.com 1
20080723 81657 300 500 tagged.com 1
20080723 214433 0 1      <------------------------------- Esta línea está mal
20080723 216642 300 500 msappspace.com 1
20080723 106863 260 433 tagged.com 1
20080723 1449 260 433 tagged.com 1


A todos esos datos los cargo en una base de datos. Todo funcionaba bien en un principio. Obviamente el script no anda... porque cuando quiero insertar en MySQL los logs, existen campos vacíos :S

Probé con muchos logs diferentes, aveces pasa y aveces no (si pasa con un log, siempre lo hace por más que probemos miles de veces más).

¿Algún consejo?... estuve toda la tarde intentando cambiar cosas... pero nada me resulto :S

Saludos

Nacho
novato_aprendiendo
Perlero nuevo
Perlero nuevo
 
Mensajes: 2
Registrado: 2008-07-30 20:03 @877

Publicidad

Notapor explorer » 2008-07-31 05:46 @282

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

Es muy extraño lo que te pasa, al fallarte unas líneas y otras no.

De todas formas, el código se puede quedar así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
sub count_lines($$) {
    my ($filename, $outputfile) = @_;

    my %seen;

    open ( INPUT, "<$filename"  ) or die("Could not open input  file stage 2");
    open ( OUTPUT,">$outputfile") or die("Could not open output file stage 2");

    while(<INPUT>) {
        chomp;
        $seen{ lc }++;
    }

    foreach my $line ( sort { $seen{$b} <=> $seen{$a} } keys %seen ) {
        print OUTPUT "$line $seen{$line}\n";
    }

    close( INPUT  );
    close( OUTPUT );
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Es decir, no te hace falta la expresión regular para quitar los finales de línea; eso se puede hacer de forma cómoda con la función chomp().
Última edición por explorer el 2008-08-01 17:15 @760, editado 2 veces en total
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 novato_aprendiendo » 2008-07-31 08:31 @397

Gracias explorer... voy a probar con tu corrección, capaz que eso era. Cuando tenga los resultados te aviso. ¡Gracias por la respuesta!
novato_aprendiendo
Perlero nuevo
Perlero nuevo
 
Mensajes: 2
Registrado: 2008-07-30 20:03 @877


Volver a Intermedio

¿Quién está conectado?

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