sábado, 4 de mayo de 2013

Abrir y escribir un fichero de texto con perl


Vamos a comenzar ver temas mas avanzados con perl al igual que con python que ya vamos en la OPP,en perl también comenzaremos a ver OPP con perl 5.x,pero primero necesitamos saber o necesito explicar algunas cosas antes,como referencias,variables especiales,manejo de archivos de texto.En una entrada pasada habia hablado sobre como abrir archivos de texto pero para su lectura,en este caso aprenderemos como escribir sobre ellos o crear nuevos archivos a partir de otros,todo esto con scripting Unix en Perl.

Esto también funciona en Windows(solo lo que diferencia es la codificacion),en mi caso estoy usando un tipo o de alguna manera similar a  Unix (Gentoo).

En este caso veremos símbolos similares a los estadares de Unix,stdin y stdout,entrada estándar y salida estándar,se parecen y de alguna manera estan influenciados pero no son iguales:

Los símbolos que vamos a usar son:


En unix redirige la salida estándar en este caso abre un archivo para escritura,al igual que unix si no existe lo crea pero si existe lo vacía para escribir el nuevo contenido.

>> 

En unix redirige la salida estándar sin borrar el contenido existente a donde es redirigido,en este caso abre un archivo para escritura,si existe escribe de bajo de el(sin borrar el demás contenido),si no existe crea uno nuevo.


En unix es la entrada estándar en este caso abre un archivo para lectura,al igual que unix no se necesita usar si es un uso básico y como lo veíamos en el otro tutorial no lo use.


+< 

Escribe al inicio de un archivo(no borra lo demas) si no existe no lo crea y regresa error.

Eso serian los estándares de Unix,para los pipes se usa también el símbolo:

|

Inicia un pipe o comando del sistema.


Bien esos símbolos ahora los vamos a usar en la sintaxis de open,asi;

open(filehandle,'simbolo archivo');

Un ejemplo de abrir un txt para lectura seria así:

open(TXT,'< archivo.txt');

De esa manera lo abre, también existe la contra parte que es cerrarlo cuando terminemos de usarlo,esta sintaxis es así:

close filehandle;

En ejemplo:

close TXT;

Igual que en el tutorial anterior podemos recorrer con un bucle todo el archivo linea por linea;

while (<TXT>) {

# Ordenes

}

Para recorrer la linea se puede usar la variable especial $_ que regresa el ultimo valor devuelto por el bucle,o podemos definir nuestra propia linea, así:

while ($linea = <TXT>) {

# Ordenes

}

En mi caso me gusta mas ($_) veamos un ejemplo:

Escribe en terminal:

printf 'Linea1\nLinea2\nLinea 3\nUltima Linea la lineA 4\n' > archivo_prueba.txt

Eso nos crea un archivo .txt con 4 lineas de nombre archivo_prueba.txt. podemos verificar con

cat archivo_prueba.txt

Ahora creamos un script en Perl para recorrerlo:

nano -w recorrer.pl

Y metemos el script:

#!/usr/bin/env perl

open (ARCHIVO,'< archivo_prueba.txt'); # Abrimos para leer

$n = 1; # Inicamos una variable para contar las lineas

while (<ARCHIVO>) { # Iniciamos un bucle basado en el filehandle

print "Linea $n : $_ \n";
 # Imprimimos linea por linea con el numero de linea

$n+=1; # Sumamos un numero por cada linea

}

close ARCHIVO; # Cerramos el archivo

Ejecutamos:




Para escribir sobre un archivo la sintaxis es sencilla,solo debemos usar el nombre del filehandle y imprimir en el:

print filehandle 'texto';

Por ejemplo podemos escribir algo corto así:


#!/usr/bin/env perl


 # Abrimos archivo para escritura


open (ARCHIVO,"> nuevo_texto.txt");


# Definimo texto con End of Data


$texto = <<"EOD";

Tiempo de Tux es un sitio de tutoriales

Para distintas plataformas de tipo Unix

Ademas de programacion scripting en Perl,Python,Bash

Existe hace casi dos años,etc,etc

EOD
 # Hasta aquí

print ARCHIVO $texto;
# Escribimos la variable texto definida con EOD

close $texto;
 # Cerramos

Ejecutamos y nos crea un archivo de nombre  nuevo_texto.txt, verificamos con:

cat  nuevo_texto.txt

Como vimos nos crear un archivo o lo vacía si ya existe el archivo con dicho nombre,para escribir al fina usamos >>,para escribir al principio +<.


Veamos un ejemplo útil:

Problema

Recorrer un archivo de configuración Unix linea por linea

Borrar los comentarios

Mandar nuevo archivo sin comentarios a nuevo archivo.

Esto lo vamos a hacer usando regex,si no los conoces date una vuelta por los tutoriales de Tiempo de Tux o googlea.

Solucion en script:

#!/usr/bin/env perl

# Usare mi archivo de conkyrc

# Abrimos conky para leer

open (CONKY,"< /home/user/.conkyrc") or die print "No se puede abir $!\n";

# or die se usa si no puede hacer algo,tambien se puede con símbolos

# Abrimos un nuevo archivo.txt para escribir.

open(NUEVO,"> conky_sin_comentarios.txt") || die "No pudo crearse: $!";

# Recorremos el conkyrc

while (<CONKY>) {

chomp($_);
 # Eliminamos saltos de carro

$_ =~ s/^[#].*//g;
 # Eliminamos comentarios con regex

print NUEVO "$_\n" if ($_ ne '');
 # Escribimos sobre el fichero nuevo

# Siempre y cuando exista algo que escribir(si no incluimos el if escribirá los espacios en blanco)
# Borren el if para que vean que pasa.
}

close CONKY;
 # Cerramos
close NUEVO;
 # Y cerramos

Si son Unixeros o Linuxeros que les gusta usar la terminal sabrán que eso se puede hacer con un pipe con sed,pero es bueno saber usar todas las herramientas.

Otro ejemplo:

Problema;

Abrir archivo de texto

Convertir todas las letras del archivo a mayúscula, excepto los comentarios

Solución:

#!/usr/bin/env perl

open (CONKY,"< /home/tenayus/.conkyrc") or die print "No se puede abir 
$!\n";

open(NUEVO,"> conky_sin_comentarios.txt") || die "No pudo crearse: $!";

while (<CONKY>) {

chomp($_);

$_ =~ tr/a-z/A-Z/ if ($_ !~ /^[#].*/);
 # Esto es lo único que llama la atención

# Convertimos todas las letras minúsculas a mayúsculas pero solo si no empieza con #
# Osea que sea un comentario

print NUEVO "$_\n";

}

close CONKY;
close NUEVO;

Eso es todo,ahora solo falta ver el uso de pipes,el cual es así la sintaxis:

'| comando'

Por ejemplo listar todos los usuarios de la tty:

#!/usr/bin/env perl

open (PIPE, "| who ");

$n = 1;

while (<PIPE>) {

chomp();

print "Linea $n : $_\n";

$n+=1;

}

close PIPE;

Eso ya se debe comprender,lo único que queda explicar es que los comandos comienzan con | a diferencia de la shell:

En shell

who | grep mi_user

En Perl:

'| who | grep mi_user'

Eso es todo :D.

No hay comentarios.:

Publicar un comentario

Los comentarios serán revisados antes de ser publicados.