• Publicidad

Retroceder línea al leer un archivo

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

Retroceder línea al leer un archivo

Notapor Ulloa » 2011-03-05 11:34 @523

Buenas tardes, necesito ayuda para resolver el siguiente problema:

Tengo un archivo con texto parecido al siguiente:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
/XXXXXXXXXX/00:00/00:05
PCKT_RCVD/21039
BAD_HCHKSM/0
PCBS_FAIL/0
/YYYYYYYYYY/00:00/00:05
net0: IPKTS/22240
net0: IERRS/0
/ZZZZZZZZZZ/00:00/00:05
DISK_ALL/8391600
DISK_FREE/1524255
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Tengo el siguiente código para que cuando se encuentre una línea que inicia con "/" y no cumpla con cierta condición todas las siguientes líneas sean ignoradas hasta encontrar una nueva línea que inicie con ese carácter y sea evaluada, y así sucesivamente. ¿Está correcto el código? ¿Hay una forma más sencilla de hacerlo?
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $c = 0;
  2. while ( $linea = <FILE> ) {
  3.     chomp();
  4.  
  5.     # Si esta iniciando o lleva flujo normal
  6.     if ( $c == 0 ) {
  7.  
  8.         # Si linea inicia con carácter /
  9.         if ( $linea =~ /^\// ) {
  10.  
  11.             # Si existe hace algo (normal)
  12.             if ( existe() ) {
  13.  
  14.                 #Hacer algo
  15.                 $c = 0;
  16.             }
  17.  
  18.             # Si no existe se modifica la bandera $c
  19.             # todas las siguientes líneas deben ser ignoradas
  20.             # hasta encontrar otra que inicie con carácter /
  21.             else {
  22.                 $c = 1;
  23.             }
  24.  
  25.             # Siguiente línea
  26.             next;
  27.         }
  28.         else {
  29.  
  30.             #Hacer algo
  31.             grabarDatos();
  32.         }
  33.     }
  34.  
  35.     # Si $c=1
  36.     # Si es una de las líneas que sigue a la
  37.     # que comienza con /
  38.     else {
  39.  
  40.         # Si se encuentra otra línea que inicia con /
  41.         if ( $linea =~ /^\// ) {
  42.  
  43.             #Hacer algo
  44.             # Se reinicia bandera
  45.             $c = 0;
  46.  
  47.             # Se manda a repetir la misma línea
  48.             redo;
  49.         }
  50.  
  51.         #Más código
  52.     }
  53.  
  54.     #Más código
  55. }
  56.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Agradeceré mucho la ayuda que puedan brindarme.
Última edición por explorer el 2011-03-05 12:09 @548, editado 1 vez en total
Razón: Formateo del código con la ayuda de perltidy; Tildes
Ulloa
Perlero nuevo
Perlero nuevo
 
Mensajes: 8
Registrado: 2011-03-04 15:36 @692

Publicidad

Re: Retroceder línea al leer un archivo

Notapor explorer » 2011-03-05 12:35 @566

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

La solución es buena y supongo que te funcionará.

Pides otra forma de hacerlo: con cambiar el orden de las condiciones (preguntar primero por la línea, en lugar de por la bandera $c) se puede ahorrar algo de código:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use common::sense;
  3. use autodie;
  4.  
  5. my $estamos_en_párrafo_interesante;
  6.  
  7. open my $FICHERO, q[<], 'kk.txt';
  8.  
  9. while (my $línea = <$FICHERO>) {
  10.  
  11.     if ($línea =~ m[^/]) {
  12.  
  13.         $estamos_en_párrafo_interesante = "sí";
  14.    
  15.         unless ( existe() ) {
  16.             undef $estamos_en_párrafo_interesante;
  17.         }
  18.  
  19.         next;
  20.     }
  21.  
  22.     if ($estamos_en_párrafo_interesante) {
  23.         grabarDatos();
  24.     }
  25. }
  26.  
  27. close $FICHERO;
  28.  
  29. __END__
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

Re: Retroceder línea al leer un archivo

Notapor Ulloa » 2011-03-05 13:12 @592

Perfecto Explorer, lo único que cambie fue una condición, porque se ejecuta grabarDatos() solo cuando existe() es verdadero.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
use common::sense;
use autodie;
my $estamos_en_párrafo_interesante;
open my $FICHERO, q[<], 'kk.txt';
while (my $linea = <$FICHERO>) {
    if ($linea =~ m[^/]) {
        $estamos_en_párrafo_interesante = "sí";
        if ( existe() ) {
            undef $estamos_en_párrafo_interesante;
        }
        next;
    }
    if (!defined($estamos_en_párrafo_interesante)) {
        grabarDatos();
    }
}
close $FICHERO;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Quizás me centré mucho en cómo volver a la iteración anterior en el loop y encontré la instrucción redo, luego me enredé. Pero tu solución me gusta mucho.

¡¡¡¡¡¡¡Muchas gracias!!!!!!!!

Desde que encontré esta página me pareció que le dedicas mucho tiempo a este sitio y que eres un verdadero didacta, y mira, lo he comprobado y muy oportuno.

Saludos,

Ulloa
Última edición por Ulloa el 2011-03-06 03:57 @206, editado 1 vez en total
Ulloa
Perlero nuevo
Perlero nuevo
 
Mensajes: 8
Registrado: 2011-03-04 15:36 @692

Re: Retroceder línea al leer un archivo

Notapor explorer » 2011-03-05 13:35 @608

Sí, ya me dí cuenta de que había escrito mal la condición del existe(), pero la arreglé enseguida con un unless(). Mira ahora el código.
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: Retroceder línea al leer un archivo

Notapor pvaldes » 2011-03-05 17:35 @774

mmh... al hilo de ésto ¿meter tildes en un nombre de variable es posible? (¿o recomendable?). Pensaba que no estaba permitido...
pvaldes
Perlero nuevo
Perlero nuevo
 
Mensajes: 129
Registrado: 2011-01-22 12:56 @580

Re: Retroceder línea al leer un archivo

Notapor explorer » 2011-03-05 18:00 @791

Ya ves que sí es posible. Desde hace ya unos años se pueden poner tildes en el código, siempre que lo actives con el pragma 'use utf8;' (yo lo activo con 'use common::sense;').

¿Recomendable? No es recomendable si escribes código que va a ser leído por otros que no sepan español.

Por lo demás, para los hispanohablantes, el código se vuelve más legible, sin tantas faltas de ortografía :)

También se puede escribir en otros idiomas, como japones, chino, koreano... o incluso latín.
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: Retroceder línea al leer un archivo

Notapor Ulloa » 2011-03-07 10:23 @474

Hola explorer, quiero aprovechar para preguntar sobre tu forma de programar en Perl. Usas muchas librerías
¿Tienes algún sitio preferido donde consultes esa información?

También hay algunas instrucciones que me parecen mas fáciles de entender de como la mayoría las utiliza por ejemplo:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$linea =~ m[^/]
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Yo lo exprese así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$linea =~ /^\//
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¿Cuál sería la diferencia?

Tenía entendido que los corchetes [] son para expresar clases y que caracteres como / se deben especificar como tales.

¿Será que estas son ventajas de utilizar librerías como common::sense, que mencionaste?

Saludos.
Ulloa
Perlero nuevo
Perlero nuevo
 
Mensajes: 8
Registrado: 2011-03-04 15:36 @692

Re: Retroceder línea al leer un archivo

Notapor explorer » 2011-03-07 12:19 @555

Ulloa escribiste:Hola explorer, quiero aprovechar para preguntar sobre tu forma de programar en Perl. Usas muchas librerías. ¿Tienes algún sitio preferido donde consultes esa información?
CPAN

Ulloa escribiste:También hay algunas instrucciones que me parecen mas fáciles de entender de como la mayoría las utiliza por ejemplo:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$linea =~ m[^/]
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Yo lo exprese así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$linea =~ /^\//
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¿Cuál sería la diferencia?
Ninguna. Sólo la escritura de la expresión regular.

Ulloa escribiste:Tenía entendido que los corchetes [] son para expresar clases y que caracteres como / se deben especificar como tales.
Sí, pero en este caso, los corchetes no definen clases de caracteres, sino que son los delimitadores del patrón.

Resulta que con los operadores m// y con s/// puedes usar los delimitadores que quieras. Tradicionalmente, se usan los '//', y por eso se puede obviar la 'm'. Pero si pones 'm', puedes poner casi cualquier delimitador.

Por ejemplo, la línea anterior se podría reescribir como $linea =~ m{^/} .

La ventaja es la siguiente: si en el patrón, hay un carácter '/' (como es este caso), y usamos los delimitadores '//', entonces estamos obligados a "escaparlo" con un '\' (como has hecho tú) para que no se confunda nuestro '/' con uno de los delimitadores. Usando corchetes (o llaves o paréntesis o ...) entonces, no es necesario "escapar" el '/'.

Ulloa escribiste:¿Será que estas son ventajas de utilizar librerías como common::sense, que mencionaste?
No. Esto es una facilidad del propio lenguaje. Más información sobre el operador m// en la sección Regexp Quote-Like Operators.
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 7 invitados