• Publicidad

Como aplicar un "grep" sobre 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.

Como aplicar un "grep" sobre un fichero

Notapor fgalves » 2007-04-16 09:27 @435

Hola a todos,

El caso es que necesito abrir un fichero y extraer únicamente las líneas que contengan un determinado string ($string). Dichas líneas (lineas útiles) son a continuación procesadas por una función determinada:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
open($fileIO,$file);
extraer_lineas_utiles($fileIO,$string);
procesar_lineas_utiles;
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Necesitaría por lo tanto aplicar algo así como un "grep" sobre dicho fichero y almacenar las líneas que contengan dicho string (líneas útiles) en otro fichero u en una estructura de datos determinada.
He buscado información sobre la instrucción en perl "grep" y por lo visto funciona únicamente con un array en entrada pero no con un fichero...

¿Alguien me puede echar una mano explicándome cuál sería la manera más simple de implementar dicho "grep"? ¿Dónde (y cómo) guardo las líneas que son extraídas?

¡Muchas gracias por adelantado!
Felipe
fgalves
Perlero nuevo
Perlero nuevo
 
Mensajes: 210
Registrado: 2006-09-25 13:54 @621

Publicidad

Notapor explorer » 2007-04-16 10:08 @464

Parece que necesitas leer todo el fichero antes de procesar las líneas. En ese caso sólo hay que aplicar el grep a todas las líneas del fichero.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
open($fileIO,$file);
my @lineas_utiles = grep { /$string/ } <$fileIO>;
procesar_lineas_utiles(@lineas_utiles);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Otra forma de hacerlo es hacer un filtrado y procesamiento por cada línea del fichero:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
open($fileIO,$file);
while ( $linea = <$fileIO> ) {
    procesar_linea_util($linea) if $linea =~ /$string/;
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
o de forma más abreviada:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
open($fileIO,$file);
while ( <$fileIO> ) {
    procesar_linea_util($_) if /$string/;
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
o de otra tercera forma
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
open($fileIO,$file);
while ( <$fileIO> ) {
    next if not /$string/;
    procesar_linea_util($_);
}
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 fgalves » 2007-04-16 10:20 @472

¡Muchas gracias por la información, Explorer!

¿Sería posible aplicar dicho grep al momento de abrir el fichero?
Algo así como:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
open($fileIO,"grep $string $file |");
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¡Gracias por adelantado!
Felipe
fgalves
Perlero nuevo
Perlero nuevo
 
Mensajes: 210
Registrado: 2006-09-25 13:54 @621

Notapor explorer » 2007-04-16 10:33 @481

Si, pero entonces estás ejecutando el grep del sistema, no el de Perl.
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: Como aplicar un "grep" sobre un fichero

Notapor Perl user » 2007-04-16 17:19 @763

Que tal,

Mira, en efecto grep funciona sobre listas, pero un archivo (al menos cómo el que quieres procesar) es una lista de líneas delimitadas por uno o mas saltos de línea (\n).

Así que implementar algo como un grep para archivos es muy trivial y puedes hacerlo incluso al estilo de grep, aquí te dejo una versión funcional:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
sub file_grep (&$) {
    my ($callback, $file) = @_;
    open my $fh, $file or die $!;
    my @ret;
    while(<$fh>) {
        # A cada línea leída la pasamos por el filtro
        # proporcionado como un coderef, si la función
        # retorna verdadero, entonces la metemos en una lista
        # que al final tendrá las lineas que nos interesan.
        push(@ret, $_ ) if $callback->();
    }
    return @ret;
}

# código de ejemplo:
my $file = 'foo.data'; # tu archivo
my @wanted_lines = file_grep { $_ =~ /PATTERN/g }, $file;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


El código no lo he probado, pero bueno espero se entienda el concepto. Cualquier duda adelante.

La idea es que file_grep procesará el archivo que le dices, y ejecutará la subrutina delimitada por {} por cada linea encontrada, y buscará el patrón indicado, almacenando en una lista las líneas que cumplen con dicho patrón.

Saludos,
Marco A. Manzo
[email protected]
http://www.unixmonkeys.com/amnesiac/
Perl Programming Language
Perl user
Maestro honorario
Maestro honorario
 
Mensajes: 271
Registrado: 2004-11-03 21:11 @924

Notapor fgalves » 2007-04-17 02:16 @136

¡Hola a todos y gracias por las propuestas!
Supongamos que finalmente uso la versión en la que se usa el grep del sistema al abrir el fichero, pues de momento me parece una solución sencilla y rápida:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
open($fileIO,"grep $string $file |");
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


En mi caso, necesito hacer un grep sobre uno o más strings: $string1, $string2, ..., $stringn. Es decir, con que uno de esos strings aparezca en la línea es suficiente para que sea considerada útil (por lo tanto el grep debe ser realizado sobre el OR de dichos strings (y no un AND)).

¿Cómo puedo hacer para hacer un grep sobre el OR de dichos strings?
¿Funcionaria lo siguiente?
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
open($fileIO,"grep $string1|$string2|$string3 $file |");
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¡Muchas gracias por adelantado!
Felipe
fgalves
Perlero nuevo
Perlero nuevo
 
Mensajes: 210
Registrado: 2006-09-25 13:54 @621

Notapor explorer » 2007-04-17 03:09 @173

No creo que sea la solución más sencilla. Puede que sea rápida, pero eso depende de cuántos y cómo sean los strings. Estamos hablando de ejecutar un binario externo, además de el propio intérprete de Perl.

No te vale el grep para agregar nomenclaturas de expresión regular. Tienes que usar el egrep (o usar grep -e).

Para 'unir' los strings con '|' en Perl se usa 'join'. Lo haces antes de hacer el 'open' y se lo pasas todo en una variable escalar.
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 Perl user » 2007-04-17 11:42 @529

fgalves escribiste:¡Hola a todos y gracias por las propuestas!
Supongamos que finalmente uso la versión en la que se usa el grep del sistema al abrir el fichero, pues de momento me parece una solución sencilla y rápida:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
open($fileIO,"grep $string $file |");
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


En mi caso, necesito hacer un grep sobre uno o más strings: $string1, $string2, ..., $stringn. Es decir, con que uno de esos strings aparezca en la línea es suficiente para que sea considerada útil (por lo tanto el grep debe ser realizado sobre el OR de dichos strings (y no un AND)).

¿Cómo puedo hacer para hacer un grep sobre el OR de dichos strings?
¿Funcionaria lo siguiente?
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
open($fileIO,"grep $string1|$string2|$string3 $file |");
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¡Muchas gracias por adelantado!
Felipe


Se ve horriblemente pésima una solución así, sin tocar puntos como portabilidad y eficiencia ya que generarás procesos a lo bruto.

No entiendo por qué la gente insiste en soluciones así cuando Perl provee herramientas mas poderosas y de la misma magnitud para resolver un problema así.

En fin... gajes del oficio.

Saludos,
Marco A. Manzo
[email protected]
http://www.unixmonkeys.com/amnesiac/
Perl Programming Language
Perl user
Maestro honorario
Maestro honorario
 
Mensajes: 271
Registrado: 2004-11-03 21:11 @924


Volver a Básico

¿Quién está conectado?

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