• Publicidad

Mostrar texto entre dos delimitadores

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

Mostrar texto entre dos delimitadores

Notapor Leo_Gutierrez » 2011-02-13 04:21 @223

Hola, tengo un archivo con:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
EventContext ABS Sales Order Screen Homepage View
SQL Statement Prepare Time for SQL Cursor with ID D118080: 0.001 seconds
SQL Statement Execute Time for SQL Cursor with ID D118080: 0.004 seconds
SQL Statement Initial Fetch Time for SQL Cursor with ID D118080: 0.001 seconds
EventContext ABS Sales Order List View
SQL Statement Prepare Time for SQL Cursor with ID 101AD370: 0.001 seconds
SQL Statement Execute Time for SQL Cursor with ID 101AD370: 0.004 seconds
SQL Statement Initial Fetch Time for SQL Cursor with ID 101AD370: 0.000 seconds
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Quiero obtener una salida algo así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
EventContext ABS Sales Order Screen Homepage View [Took 0.006 ]
EventContext ABS Sales Order List View [Took 0.005 ]
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Es decir, hacer una sumatoria sobre los tiempos. Pero me encuentro con el problema del rango entre textos, no sé cómo manejarlo.

¿Podrían darme una ayuda?

Debe ser algo parecido a sed:

Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
  1. [leo@archero Desktop]$ cat file.txt | sed -n "/Even/,/Event/p"
  2. EventContext ABS Sales Order Screen Homepage View
  3. SQL Statement Prepare Time for SQL Cursor with ID D118080: 0.001 seconds
  4. SQL Statement Execute Time for SQL Cursor with ID D118080: 0.004 seconds
  5. SQL Statement Initial Fetch Time for SQL Cursor with ID D118080: 0.001 seconds
  6. EventContext ABS Sales Order List View
  7. [leo@archero Desktop]$
  8.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


En fin, cualquier ayuda es bien recibida.

Tengo un avance, con esto logro obtener el texto:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. while(<$file>)
  2. {
  3.         if(!/Event/.. !/Event/)
  4.         {
  5.                 print;
  6.         }
  7. }
  8.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Pero, ¿cómo saber en qué parte del texto estoy? Esto lo necesito para las sumatorias.

Otra duda, ¿cómo puedo asignar el contenido de un archivo a un escalar? Quiero ver si puedo aplicar una expresión regular. He intentado con $line = <$file>, pero no.

Saludos.
Última edición por Leo_Gutierrez el 2011-02-14 17:21 @764, editado 1 vez en total
Leo_Gutierrez
Perlero nuevo
Perlero nuevo
 
Mensajes: 91
Registrado: 2008-08-20 23:38 @026

Publicidad

Re: Mostrar texto entre dos delimitadores

Notapor explorer » 2011-02-13 06:07 @296

Bueno, no es necesario usar rangos para resolver este caso.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use common::sense;
  3.  
  4. open IN,  q[<], 'kk.txt';
  5. open OUT, q[>], 'kk.txt.out';
  6.  
  7. my $cabecera = '';
  8. my $total    = 0;
  9.  
  10. while (my $línea = <IN>) {
  11.     given($línea) {
  12.         when(/^EventContext/) {
  13.             sumatorio();
  14.             chomp($cabecera = $línea);
  15.         }
  16.         when (/([\d.]+) seconds/) {
  17.             $total += $1;
  18.         }
  19.     }
  20. }
  21.  
  22. sumatorio();
  23.  
  24. close IN;
  25. close OUT;
  26.  
  27. sub sumatorio {
  28.     return if not $cabecera;
  29.     print OUT "$cabecera [Took $total]\n";
  30.     $cabecera = '';
  31.     $total    = 0;
  32. }
  33.  
  34. __END__
  35. EventContext ABS Sales Order Screen Homepage View [Took 0.006]
  36. EventContext ABS Sales Order List View [Took 0.005]
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Con rangos, habría que tener en cuenta el caso de llegar al final del fichero (no más líneas Event).

Para asignar el contenido de un fichero a un escalar, se puede realizar de varias formas.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
open my $fh, q[<], 'kk.txt';
my $fichero = join q[], <$fh>;    # muy ineficiente
close $fh;

open my $fh, q[<], 'kk.txt';
undef $/;
my $fichero = <$fh>;              # modo "slurp". La variable $/ indica que no se miren los finales de línea
close $fh;

my $fichero = do { undef $/; open K, 'kk.txt'; <K> };   # Típico modismo de Perl

use File::Slurp;
my $fichero = read_file('kk.txt');                      # Usando un módulo
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: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Mostrar texto entre dos delimitadores

Notapor wanako » 2011-02-14 02:27 @144

Suponiendo que cada línea [EventContext...] es única, podemos también usar un hash:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4.  
  5. open IN,  q[<], 'kk.txt';
  6. open OUT, q[>], 'kk.txt.out';
  7.  
  8. my ( %events, $cabecera, $seconds );
  9.  
  10. while ( <IN> ) {
  11.         if ( /(^Event.+)/ ) {
  12.                 $cabecera = $1;
  13.                 $seconds = 0;
  14.         }
  15.         if ( /(\b[\d.]+\b)/ ) {
  16.                 $seconds = $1;
  17.         }
  18.         $events{$cabecera} += $seconds;
  19. }
  20.  
  21. foreach ( keys %events ) {
  22.         print OUT qq[$_ [ Took $events{$_} ]\n];
  23. }
  24.  
  25. close IN;
  26. close OUT;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
wanako
Perlero nuevo
Perlero nuevo
 
Mensajes: 27
Registrado: 2010-09-23 11:27 @519

Re: Mostrar texto entre dos delimitadores

Notapor Leo_Gutierrez » 2011-02-14 16:21 @723

@wanako, el problema es que son varias.

explorer, estudiaré tu solución y veré cómo la modifico. Gracias.

EDITO:

explorer, al usar tu script me da esto:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
readline() on closed filehandle IN at code.pl line 10.
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Tuve que instalar common::sense para poder probar tu script. Cambié el script a lo siguiente y ya funciona.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. open(my $file,  q[<], 'file.txt') or die("Error abriendo archivo. $!");
  2.  
  3. my $cabecera = '';
  4. my $total    = 0.0;
  5.  
  6. while(my $linea = <$file>)
  7. {
  8.    
  9.         if($linea =~ /^EventContext/) {
  10.             sumatorio();
  11.             chomp($cabecera = $linea);
  12.         }
  13.         if($linea =~ /([\d.]+) seconds/) {
  14.             $total += $1;
  15.         }
  16. }
  17.  
  18. sumatorio();
  19.  
  20. close($file);
  21.  
  22. sub sumatorio
  23. {
  24.     return if not $cabecera;
  25.     print "$cabecera [Took $total]\n";
  26.     $cabecera = '';
  27.     $total    = 0;
  28. }
  29.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Leo_Gutierrez
Perlero nuevo
Perlero nuevo
 
Mensajes: 91
Registrado: 2008-08-20 23:38 @026


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: Google [Bot] y 0 invitados