• Publicidad

Seleccionar líneas de 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.

Seleccionar líneas de un archivo

Notapor lis » 2014-08-19 17:15 @760

Hola a todos. Les pido su ayuda nuevamente.

Les explico: Al archivo adjunto llamado CO.txt necesito extraerle las líneas 3694-3757 y 6323-6386, guardando cada rango en un archivo.

Cabe destacar que las líneas en cada archivo (que son varios) siempre varían.

Hice el siguiente código, pero en el archivo de salida hay muchas más líneas de las que necesito, pero es lo más cercano que he conseguido.

Nuevamente les agradezco su ayuda y muchas gracias.

#!/usr/bin/perl
use strict;
use warnings;

while(my $file=<*.txt>){

my $nombre=substr($file,0,-4);

my $salida= $nombre . '.dat';
open my $out, ">$salida" or die;

open(FICHERO2, "<$file") or die "$!\n";
while (<FICHERO2>) {
chomp;
my @c = split(" ", $_);

if ($_ =~ m/(([0-9])* (\s?) ([-][0-9]\.+[0-9]))/){
print $out $_;

}}
close FICHERO2;
close $out;
}
Adjuntos
CO.txt
(782.43 KiB) 75 veces
lis
Perlero nuevo
Perlero nuevo
 
Mensajes: 106
Registrado: 2008-05-27 21:43 @946

Publicidad

Re: Seleccionar líneas de un archivo

Notapor explorer » 2014-08-19 19:33 @856

Perl nació como procesador rápido de textos, para hacer resúmenes e informes, así que este tipo de problemas son muy fáciles de resolver.

Tanto, que ni siquiera necesitas un programa para hacerlo. Desde la misma línea de comandos puedes resolverlo:

Sintáxis: [ Descargar ] [ Ocultar ]
  1. perl -nE 'print if 3694..3757 or 6323..6386' CO.txt > salida.txt 
Explicación:
  • el archivo de texto CO.txt es pasado como argumento, por lo que es abierto en lectura
  • la opción -n hace una lectura por todas las líneas del archivo, donde ejecutará el programa indicado por -E en cada una de ellas
  • el programa es un simple print() que se ejecutará si la condición que sigue al if() es cierta
  • como no hemos indicado ningún argumento a print(), éste hará un print($_). Y como $_ almacena la línea leída, pues print() sacará las líneas que nos interesa
  • la condición consiste en dos condiciones unidas por un 'or', así que será cierta si cualquiera de las dos son ciertas
  • las condiciones son operadores rango, que normalmente se usan para generar números, pero al estar en una condición, tienen algo de "magia" escondida. Esa magia consiste en hacer comprobar si la condición se cumple dentro de los márgenes indicados por los operandos del rango. Y al ser numéricos, la condición se aplica al valor de la variable $., que es la variable especial que almacena el valor del número de línea leído hasta ahora.
El programa se podría leer como... «imprime la línea leída si el número de línea leída está entre 3694 y 3757, o 6323 y 6386».

Finalmente, la salida del programa es redirigida hacia salida.txt, con lo que el problema queda resuelto.

Ahora bien... podemos hacerlo más fuerte.

¿Qué ocurre si el formato del archivo cambia en el futuro? ¿ Qué pasará si ya no coinciden los números de línea? Tendremos que volver a abrir el archivo y ver donde están las nuevas líneas.

Podemos plantearnos realmente qué queremos.

Y lo que queremos no es extraer unas líneas en una determinada posición, si no que lo que queremos es sacar los valores de concentración en cada receptor discreto.

Bueno, pues eso es lo que le diremos a Perl que haga:

Sintáxis: [ Descargar ] [ Ocultar ]
  1. perl -nE 'print if /CONCENTRATION VALUES AT EACH DISCRETE RECEPTOR/ .. /^[*]+/ and /^  /' CO.txt > salida.txt 
En este caso, le estamos diciendo a Perl que mire solo las líneas que están entre el título que queremos, y el final de la tabla (las líneas con caracteres '*'). Y de todas ellas, solo nos interesa las líneas que tengan al menos tres espacios en blanco delante (esa es la característica que distingue a las líneas de datos del resto).

Ahora ya sí que tenemos un programa robusto: aunque cambie el formato del archivo, y las líneas estén en sitio distinto, Perl las podrá encontrar.
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: Seleccionar líneas de un archivo

Notapor lis » 2014-08-21 16:51 @744

Muchas gracias, ¡¡funcionó excelente!! Además, me encantó la simplicidad.
lis
Perlero nuevo
Perlero nuevo
 
Mensajes: 106
Registrado: 2008-05-27 21:43 @946


Volver a Básico

¿Quién está conectado?

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