• Publicidad

Más de expresiones regulares

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

Más de expresiones regulares

Notapor migbur » 2015-01-28 09:42 @446

Hola.

Me estoy iniciando en Perl y quiero filtrar algunas líneas de una salida, esto es: un resumen, puesto que la salida es más larga.
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
A3/APT "M#DEL5R 711BIPA" 288 150128   1113      
RADIO X-CEIVER ADMINISTRATIN
TRANSCEIVER GROUP FAULT

MO                                 RSITE           ALARM SLOGAN
RXOTG-321                          00083#COLLAD#D  BTS INTERNAL



A3/APT "M#DEL5R 711BIPA" 291 150128   1119      
DIGITAL PATH FAULT SUPERVISION

DIP      DIPEND   FAULT     SECTION   HG  DATE    TIME
RBLT118           RDI                     150128  111915
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Quiero: La primera línea que coincida con RXOTG-321.

Este sería el resultado final:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
A3/APT "M#DEL5R 711BIPA" 288 150128   1113 ALARM SLOGAN  BTS INTERNAL
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Espero que alguien me ayude:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. @output=$telnet->cmd('hostname');
  2. @line_split =  split (/\n/, $output);
  3. foreach my $line (@line_split)
  4. {
  5. if($line_split=~/RXOTG-X/)#Mi conocimiento no llega a más. No sé cómo imprimir la línea anterior
  6.   {  
  7.      print ("Line: $line\n");
  8.   }
  9. }
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4
Última edición por explorer el 2015-01-28 10:21 @473, editado 1 vez en total
Razón: lineas => líneas; output => salida; mas => más; seria => sería; se => sé; como => cómo;
migbur
Perlero nuevo
Perlero nuevo
 
Mensajes: 4
Registrado: 2014-12-19 07:04 @336

Publicidad

Re: Más de expresiones regulares

Notapor explorer » 2015-01-28 10:29 @479

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

O sea... el problema se puede expresar así: si se detecta la clave que se está buscando, hay que sacar la primera línea que comienza por A3, seguido por el texto final de la línea anterior a la clave, junto con el texto final de la línea actual.

¿Es eso?
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: Más de expresiones regulares

Notapor migbur » 2015-01-28 17:07 @755

Hola.

Gracias por tu respuesta.

Sí, sería eso, pero no me cuadra el cómo sabe Perl cuál es la primera línea que pertenece a esa coincidencia RXOTG-321.

Tal vez no me expliqué bien, pero es un log con más datos arriba y abajo.

Imagina que quiero los datos de todas las coincidencias que contengan RXOTG-321.

En pocas palabras: quiero filtrar las alarmas que coincidan con RXOTG-321.

Esta sería la salida completa:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
A3/APT "M#DEL5R 711BIPA" 276 150128   0930      
DIGITAL PATH QUALITY SUPERVISION

SES
DIP      DIPPART  SESL2  QSV    SECTION  DATE    TIME
RBLT149           1      1               150128  093000


A3/APT "M#DEL5R 711BIPA" 287 150128   1111      
DIGITAL PATH QUALITY SUPERVISION

SESR
DIP      DIPPART  SESL2  QSV    SECTION  DATE    TIME
RBLT80            1      1               150128  111142


A3/APT "M#DEL5R 711BIPA" 288 150128   1113      
RADIO X-CEIVER ADMINISTRATION
TRANSCEIVER GROUP FAULT

MO                                 RSITE           ALARM SLOGAN
RXOTG-321                          00083#COLLAD#D  BTS INTERNAL



A3/APT "M#DEL5R 711BIPA" 291 150128   1119      
DIGITAL PATH FAULT SUPERVISION

DIP      DIPEND   FAULT     SECTION   HG  DATE    TIME
RBLT118           RDI                     150128  111915


A3/APT "M#DEL5R 711BIPA" 292 150128   1120      
DIGITAL PATH QUALITY SUPERVISION

SF
DIP      DIPPART  SFL    QSV
RBLT80            5      27

A3/APT "M#DEL5R 711BIPA" 917 150125   0237      
RADIO X-CEIVER ADMINISTRATION
TRANSCEIVER GROUP FAULT

MO                                 RSITE           ALARM SLOGAN
RXOTG-100                          03626#MAJESP#G  BTS INTERNAL



A3/APT "M#DEL5R 711BIPA" 964 150125   1600      
RADIO X-CEIVER ADMINISTRATION
TRANSCEIVER GROUP FAULT

MO                                 RSITE           ALARM SLOGAN
RXOTG-103                          02755#MAJARD#G  BTS INTERNAL



A3/APT "M#DEL5R 711BIPA" 017 150126   1142      
RADIO X-CEIVER ADMINISTRATION
TRANSCEIVER GROUP FAULT
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


De la salida quisiera filtrar todas las coincidencias, que en este caso serían:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
A3/APT "M#DEL5R 711BIPA" 288 150128 1113
RADIO X-CEIVER ADMINISTRATION
TRANSCEIVER GROUP FAULT

MO RSITE ALARM SLOGAN
RXOTG-321 00083#COLLAD#D BTS INTERNAL
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Y luego modificar el filtro para que imprima
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
A3/APT "M#DEL5R 711BIPA" 288 150128   1113 ALARM SLOGAN  BTS INTERNAL
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Todo el log lo tengo dentro de un escalar que leo línea por línea con el foreach(), pero no sé cómo filtrar una línea que ya fue leída por que la coincidencia esta 6 líneas más abajo.
Última edición por explorer el 2015-01-28 21:25 @934, editado 2 veces en total
Razón: Si => Sí; seria => sería; como => cómo; cual => cuál; linea => línea; explique => expliqué; mas => más; se => sé; como => cómo; leida => leída; mas => más;
migbur
Perlero nuevo
Perlero nuevo
 
Mensajes: 4
Registrado: 2014-12-19 07:04 @336

Re: Más de expresiones regulares

Notapor explorer » 2015-01-28 21:36 @942

Bueno, entonces queda claro que las secciones comienzan por A3/APT, y consisten en una cabecera, una línea en blanco, luego un contenido, y luego más líneas en blanco hasta la siguiente sección.

Puedes ir viendo de línea en línea con el foreach(), y dentro de él, mirar a ver si la línea comienza por A3/APT (por ejemplo, con la función index()); si es así, inicializamos la variable $cabecera y vamos guardando todas las líneas en ella, hasta que encontremos una línea en blanco (este control se puede hacer con una variable que haga de bandera).

Luego comienza el cuerpo. Vamos leyendo líneas y guardándolas en un array (que habremos inicializado en el if() anterior). Y al mismo tiempo vemos si cada línea contiene lo que buscamos (con index(), otra vez). Si es así, levantamos otra bandera.

Cuando encontremos otra línea en blanco, comprobamos si hemos encontrado lo que queremos, y en ese caso, repasamos el array y sacamos lo que nos interesa.

De esta última parte, no queda claro qué es lo que hay que hacer. Parece que quieres extraer las dos últimas palabras de cada línea.
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: Más de expresiones regulares

Notapor explorer » 2015-01-31 06:51 @327

Bueno, esta es una de las posibles soluciones, usando la técnica de la máquina de estados:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use v5.18;
  3. use experimental 'smartmatch';
  4. use utf8::all;
  5.  
  6. use constant {
  7.     CABECERA => 0,
  8.     CUERPO   => 1,
  9.     SECCION  => 2,
  10.     FUERA    => 3,
  11. };
  12.  
  13.  
  14. @ARGV == 2 or die "Uso: $0 <clave> <archivo>\n";
  15.  
  16. my $clave = shift @ARGV;
  17.  
  18. my $sección = FUERA;                                   # estado inicial
  19. my $cabecera;                                           # almacenes
  20. my @cuerpo;
  21.  
  22. while (my $línea = <>) {
  23.  
  24.     for ($sección) {
  25.         when (FUERA) {                                  # estamos fuera de sección
  26.             if ($línea =~ m{^A3/APT}) {                        # detectada inicio de sección
  27.                 $cabecera = $línea;
  28.                 $sección = CABECERA;
  29.             }
  30.         }
  31.         when (CABECERA) {
  32.             if ($línea =~ m{^\s*$}) {                  # detectada final de cabecera
  33.                 $sección = SECCION;
  34.             }
  35.         }
  36.         when (SECCION) {
  37.             if ($línea =~ m{^\S}) {                    # detectado cuerpo
  38.                 $sección = CUERPO;
  39.                 continue;
  40.             }
  41.         }
  42.         when (CUERPO) {
  43.             if ($línea =~ m{^\s*$}) {                  # detectado final del cuerpo
  44.  
  45.                 if (grep {/\b$clave\b/} @cuerpo) {      # encontrada clave
  46.                     $cabecera =~ s/\s+$//;
  47.  
  48.                     for (@cuerpo) {                     # formatear cuerpo
  49.                         chomp;
  50.                         $_ = substr $_, 51;
  51.                     }
  52.  
  53.                     say "$cabecera ", join "  ", @cuerpo;
  54.                 }
  55.  
  56.                 $sección = FUERA;
  57.                 undef @cuerpo;
  58.             }
  59.             else {
  60.                 push @cuerpo, $línea;                  # seguir almacenando
  61.             }
  62.         }
  63.     }
  64.  
  65. }
  66.  
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: Más de expresiones regulares

Notapor migbur » 2015-02-12 09:20 @431

Hola, compañeros. Para no dejar en el aire este hilo, así quedó finalmente.

Lo único que no me fue posible hacer un solo if() con las dos expresiones. Intenté con

if ($linea =~/^RXO(\w+)-$tg(\s/||/^RXO(\w+)-$tg-/)

pero no funciona.

Así quedó:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. open my $allip, "allip.txt";
  2. while ( my $linea = <$allip> ) {
  3.     if ( $linea =~ /^A/ ) {
  4.         $header = $linea;
  5.         chop($header);
  6.  
  7.         #print"$header\n";
  8.     }
  9.     if ( $linea =~ /^RXO(\w+)-$tg(\s)/ ) {
  10.  
  11.         my @linea_split = split( /\s+/, $linea );
  12.  
  13.         #shift @linea_split;
  14.  
  15.         print "$header @linea_split\n\n";
  16.     }
  17.     if ( $linea =~ /^RXO(\w+)-$tg-/ ) {
  18.  
  19.         my @linea_split = split( /\s+/, $linea );
  20.  
  21.         #shift @linea_split;
  22.  
  23.         print "$header @linea_split\n\n";
  24.     }
  25.  
  26.     close allip . txt;
  27. }
  28.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Última edición por explorer el 2015-02-12 10:19 @472, editado 1 vez en total
Razón: asi => así; quedo => quedó; intente => intenté; Formateado de código con perltidy; unico => único;
migbur
Perlero nuevo
Perlero nuevo
 
Mensajes: 4
Registrado: 2014-12-19 07:04 @336

Re: Más de expresiones regulares

Notapor explorer » 2015-02-12 10:30 @479

Hay una pequeña diferencia entre los dos patrones en las expresiones regulares, así que se puede resumir en una sola:

/^RXO(\w+)-$tg(?:\s|-)/

Es decir: lo que sigue a $tg, es una alternancia de dos valores: o un espacio en blanco o un guión.

Entonces, el código queda así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. open my $allip, "allip.txt";
  2. while ( my $linea = <$allip> ) {
  3.     if ( $linea =~ /^A/ ) {
  4.         $header = $linea;
  5.         chomp $header;
  6.  
  7.         #print"$header\n";
  8.     }
  9.     if ( $linea =~ /^RXO(\w+)-$tg(?:\s|-)/ ) {
  10.  
  11.         my @linea_split = split " ", $linea;
  12.  
  13.         #shift @linea_split;
  14.  
  15.         print "$header @linea_split\n\n";
  16.     }
  17. }
  18. close $allip;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Revisa tu código, porque el close() lo tenías mal.
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 8 invitados