		Tema VIII
		Programacin en PERL.


PERL.

PERL es un lenguaje creado para extraer datos y generar reportes utilizando
un lenguaje. Dicho lenguaje es una combinacin de scripts de UNIX y lenguaje
C.

PERL es un lenguaje interpretado, por lo tanto no se debe compilar.

PERL es un lenguaje que se puede encontrar de dominio pblico y disponible
para varias plataformas.

+ Instrucciones en PERL.

PERL acepta un conjunto de instrucciones y palabras reservadas. Por cada
sentencia o instruccin, se debe terminar con un smbolo de punto y coma (;).


+ Datos escalares.

Para PERL un dato escalar es un nmero o una cadena de caracteres.


Algunos ejemplos de valores numricos que puede adquirir PERL son:

12
-2004
1.25
2.99e8
-1.23e-43

Una cadena de caracteres est compuesta por caractares ASCII de 0 a 255.
Una cadena de caracteres puede representarse como un conjunto de caracteres
limitados por comillas sencillas o comillas dobles.
'hello'     cadena hello
'hello\'t'  cadena hello't
'c:\\\\'    cadena c:\\
'hello	     cadena hello		
world'              world

las comillas dobles se usan para especificar caracteres de control como
tabulador, salto de linea.

"hello\n"
"hello\tbye"

La diferencia entre la comilla sencilla y doble, es que una cadena de
caracteres escrita dentro de una comilla sencilla no interpreta los caracteres
y con doble comilla si los interpreta.

+ Operadores.

Para nmeros existe +,-,*, /. Dos nmeros enteros divididos entre si, pueden
retornar un nmero flotante. El operado para exponente es **.

Los operadores de comparacin son < <= ==  >= > !=, para comparar dos valores
numricos.

Para cadena de caracteres se utiliza el operador ., que permite concatenar
cadenas de caracteres.

"hola".'mundo'

Existen operadores para compara cadena de caracteres y son: eq, ne, lt,gt, le,
ge. Las siguientes expresiones todas dan verdadero (o 1).

'hola' eq "hola"
'hola' ne 'adios'
'hola' lt 'hola mundo'
'7' gt '30'
'30' ge '120'

Se puede aplicar un operador para repetir cadenas de caracteres, conocido como
x.

'hola'x3  (escribe holaholahola)
"gus"x(4+4) (gusgusgusgusgusgusgusgus)


+ Variables escalares.

Una variable escalar almacena datos escalares. Una variable escalar se 
define con el signo de $, seguido de una letra, seguido de nmeros, letras
o _. PERL es case sensitive, por lo que la variable $a es diferente a $A.

$a=15; #a vale 15
$b= $a + 5;  #b vale 20
$nombre= 'gus'; #nombre vale gus
$d= ($c=5);     #d y c valen 5.
$a+=5;		#a vale 20
$nombre= $nombre." de la cruz"; #nombre vale gus de la cruz
$nombre.= " tovar"; #nombre vale gus de la cruz tovar
$d= ++$b #d y b valen 21
$c= $b++ #c vale 21 y b vale 22
$linea="hello world";
$ch=chop($linea) #linea vale hello worl y ch vale d
$linea="hello world\n";
chomp($linea) #linea vale hello world sin nueva linea.


+ Interpolacion.

Si un mensaje se quiere escribir con la combinacin de texto y variaables
escalares, se puede definir una cadena de caracteres con dobles comillas.

Suponiendo

$a="enojado";
$mensaje="estoy $a";  #mensaje vale estoy enojado
$mensaje='estoy $a';   #mensaje vele estoy $a

+ Entrada del usuario.

Para que un programa en PERL lea la entrada del usuario, es necesario
utilizar el manejador de entrada estndar, <STDIN>

$a= <STDIN>; #a vale lo que entre el usuario, seguido del enter
chomp($a); #se suprime el enter;


+ Salida.

La rutina print permite imprimir un mensaje.
$a="este es un mensaje";
print($a."\n");


Ejercicios.
1. Escribir un programa que calcule la circunferencia de un circulo con radio
de 12.5.
2. Modificar el ejercicio 1 para que le pregunte al usuario el valor del
radio.
3. Escribir un programa que pregunte dos nmero e imprima el resultado
de su multiplicacin.
4. Escribir un programa que pregunte un string y un numero e imprima el
string el numero de veces indicado, separado por una linea (utilizar el
operado x )

+ Listas y arreglos.

PERL define una lista como un conjunto de datos escalares.
Un arreglo es una VARIABLE cuyo valor es una lista.
Para accesar cada elemento de la lista, se debe utilizar la variable de tipo
arreglo, proporcionando un ndice que va de 0 a n-1, donde n es el tamao de
la lista.

Una lista es lo siguiente:

@arreglo1=(1,2,3); 
print @arreglo1; #arreglo1 es una variable con valor (1,2,3)
$a=$b=$c=1;
@arreglo2=($a,$b,$c); #arreglo2 es una variable con valor (1,1,1)
print @arreglo2;
@arreglo3=(); #lista vacia
@arreglo4= (1..100); #lista abreviada, va de 1 a 100
print @arreglo4;

Una lista encierra entre parntesis a cada elemento, y separa a cada elemento
con coma. 
Una variable arreglo, se define con el smbolo @, seguido de una literal,
seguido de literal, nmero o _.

Cuando se imprime la lista, esta se imprime sin espacios. Para lograr
que se imprima con espacios, se debe interpolar la variable.

@arreglo=(1..10); #arreglo con valor de 1 a 10
print @arreglo,"\n"; #imprime de 1 a 10 sin espacio
print "@arreglo \n"; #imprime de 1 a 10 con espacio

Para accesar un elemento de la lista

@arreglo=(1,2,3,4);
print @arreglo[2],"\n"; #accesar elemento  2, en este caso 3
print @arreglo[$#arreglo],"\n"; #accesar ultimo elemento, en este caso 4
print @arreglo[-1],"\n"; #-1 implica que cuenta a partir del extremo de la lista

La expresion $#arreglo obtiene el valor del ltimo indice del arreglo.

Para aadir un elemento a lista
@arreglo=(1..4);
@arreglo[4]=0;
print "@arreglo","\n";

Cuando se lee la entrada estandar y se asigna el resultado a un arreglo,
PERL deja de preguntar al usuario hasta que encuentra fin de archivo.

#!/opt/LWperl/bin/perl

@archivo=<STDIN>;

print "Primera linea: @archivo[0]";
print "Ultima linea: @archivo[$#archivo]";

Al correr este ejemplo

Ejemplo1.pl < /etc/passwd
Primera linea: root:x:0:1:Super-User:/:/sbin/sh
Ultima linea: oracle:x:1002:101:Cuenta ORACLE:/opt/oracle:/bin/csh

+ Asignacion de variables con listas.

Muchas veces se encuentra este tipo de expresiones.

@arreglo=($a,$b,$c)=(1,2,3); #a=1,b=2,c=3
print $b,"\n";
print "@arreglo"

Cada variable escalar se asigna su respectivo valor de la lista.
Ademas se puede referencia la lista con la variable arreglo.

Se puede asignar un arreglo que contenga dos listas

@arreglo=(1..3);
@arreglo=(@arreglo,@arreglo);
print "@arreglo";
print $#arreglo;

+ Funciones sobre listas.

Se puede tratar una lista como una pila o stack. Para esto se utiliza
la funcin push y pop, que insertan o remueven el ltimo elemento de la lista.
La funcin pop retorna el elemento que remueve.

@stack=qw(elemento1 elemento2 elemento3);
print "@stack\n";
push(@stack,"elemento4");
print "push->@stack\n";
$tope= pop(@stack);
print "Tope -> $tope\n";
print "Pop->@stack";

La funcin qw pone a cada elemento de la lista entre dobles comillas.

La funcin ushift y shift permiten, respectivamente,
 insertar o borrar elementos al principio de la lista.

@argumentos=qw(nombreprograma arg1 arg2 arg3);
print "@argumentos\n";
unshift(@argumentos,"nuevoargumento"); #annade nuevoargumento al inicio
print "unshift--> @argumentos \n";
$inicio=shift(@argumentos); #remueve el elemento nuevoargumento
print "Inicio->$inicio","\n";
print "shift--> @argumentos \n";

La funcin reverse invierte el orden de la lista

@arreglo=(1..10);
@tmp=reverse(@arreglo);
print "@tmp\n";

+ Contexto.
Cuando un arreglo se imprime con la funcion print, PERL lo trata como una
lista, dado que su contexto esta dentro de una funcion que lo trata como
una lista.
Pero si el contexto es un escalar, un entero, lo trata como el ltimo ndice
del arreglo.

@arreglo=(1..10);
print "@arreglo \n";
$longitud=@arreglo;
print "longitud $longitud\n";

Ejercicios.
1. Escribir un programa que lea una lista de cadena de caracteres de la
entrada estndar y las muestre en orden inverso.

2. Escribir un programa que lea un nmero y luego una lista de cadena de
caracteres separadas por nueva linea, e imprima la linea dada por el numero.


+ Instrucciones de control.


PERL, como cualquier otro lenguaje, proporciona instrucciones para controlar
condiciones, ciclos.

Para PERL un valor verdadero es una cadena de caracteres vaca ("") o una cadena
de caracteres con valor "0". Cualquier otra cosa es verdadero. 

Si un valor escalar es encontrado dentro de un contexto de prueba condicional,
este es convertido a cadena de caracteres.

Un bloque de instrucciones en PERL se comienza con el smbolo { y se concluye
con el smbolo }. Dentro de las llaves se pueden inscribir instrucciones PERL.


La primera instruccin de control es if-else, que tiene la siguiente estructura.

if (una-expresion ) {

	#bloque
} elsif (otra expresion) {
	#bloque
} else {
	#bloque
}

El siguiente ejemplo muestra el uso de if-else
#!/opt/LWperl/bin/perl

$nombre=<STDIN>; #obtiene un nombre de la entrada estandar
chomp($nombre);
if ($nombre eq "Darth Maul") {
	print "Tu eres el aprendiz\n";
} elsif ($nombre eq "Darth Sidious" ) {
	print "Tu eres el maestro\n";
} else {
	print "Espero que no seas Anakin\n";
} 

Existe otra instruccion, denominada unless (a menos que), que permite
evaluar una expresion y a menos que sea falsa, se ejecuta el bloque
de instrucciones.

unless (expresion) {

	#bloque
}


#!/opt/LWperl/bin/perl

$nombre=<STDIN>; #obtiene un nombre de la entrada estandar
chomp($nombre);
unless ($nombre ne "Anakin") {
	print "No puedes ser entrenado\n";
} 

Para ciclos, se puede utilizar la instruccin while-until, con la siguiente
estructura.

while (expresion) {
	#bloque

}

#!/opt/LWperl/bin/perl

@preguntas=("Esposa de Anakin\n","Maestro de Anakin\n","Amo de Anakin\n");
@respuestas=("Amidhala","Obi-Wan Kenobi","Palpatine");

$i=0;

while ($i< @preguntas) {

	print @preguntas[$i];
	$respuesta= <STDIN>;
	chomp($respuesta);
	if ( @respuestas[$i] eq $respuesta ){
		print "Correcto\n";
		last; #romper el ciclo
	}
	$i++;
}


La instruccin last concluye el ciclo.

Otra estructura de control es until, que realiza un ciclo mientras una
condicin no sea verdadera.

until (expresion) {
	#bloque
}

#!/opt/LWperl/bin/perl

@preguntas=("Esposa de Anakin\n","Maestro de Anakin\n","Amo de Anakin\n");
@respuestas=("Amidhala","Obi-Wan Kenobi","Palpatine");

$i=$ultimo=@preguntas-1;

until ($i < 0 ) {

	print @preguntas[$i];
	$respuesta= <STDIN>;
	chomp($respuesta);
	if ( @respuestas[$i] eq $respuesta ){
		print "Correcto\n";
		last;
	}
	$i--;
}

Existe instruccin de control do-while, para ejecutar una instruccin una o
mas veces, mientras la condicin sea cierta.

do {

} while expresion;

#!/opt/LWperl/bin/perl

@platillos=("sopa","arroz","milanesa","flan");

$i=0;

do {

	print "Que quieres de comer\n"; 

	$orden= <STDIN>;
	chomp($orden);
	$i++;
}while $orden eq @platillos[$i-1] && $i<@platillos;


Otra instruccin que existe es do until, que realiza el ciclo hasta que
se cumple una condicin.

#!/opt/LWperl/bin/perl

$deseos=1;
do {

	print "Que deseas\n"; 

	$orden= <STDIN>;
	chomp($orden);
	$deseos++;
}until $deseos > 3 ;

El estructura de control for es de la siguiente forma:

for (expresion inicial; condicion; siguiente-paso)  {
	bloque

}


#!/opt/LWperl/bin/perl

for ($i=10;$i>=0;$i--)  {
	@numeros[$i]=$i;
}

for ($i=0;$i<@numeros;$i++)  {
	print "Numero ",@numeros[$i], " Cuadrado ",@numeros[$i]*@numeros[$i],"\n";
}

Otra instruccin es foreach, que toma una lista de valores y en cada paso
del ciclo, asigna un valor a la variable de control.

foreach $variable (lista) {
	#bloque
}

#!/opt/LWperl/bin/perl

@operas=("El Oro del Rin","La Valkiria","Sigfrido","El Ocaso de los Dioses");

print "Las operas que componen la tetralogia del Anillo son\n";
foreach $opera (@operas)  {
	print $opera,"\n";
}

@episodios=("The Phantom Menace","","","A new Hope","The Empire Strikes Backs","Return of the Jedi");

print "Los nombres de las peliculas de Star Wars son:\n";
foreach $i (0,3,4,5) {

	print @episodios[$i],"\n";
	
}

Ejercicios.
1. Escribir un programa que pregunte la temperatura e imprima "muy alta" si
es igual o mayor a 30, si est entre 29.9 y 21, "normal"; de lo contrario, 
"muy frio".
2. Escribir un programa que pregunte por cada linea, un nmero, usando -1 como
valor de salida. Cuando se de el valor de salida, se efecta una suma de
todos los nmeros ingresados.
3. Que realiza el siguiente programa:
#!/opt/LWperl/bin/perl

@lista=<STDIN>;

while (@lista) {
	print pop @lista;
}



+ Variables Hash.

Una variable hash es un lista de elementos, donde la lista de los
elementos es indexada por algo diferente a un nmero, conocido como llaves.

Una variable hash queda representada con el smbolo de %.

Un ejemplo de una lista hash es:

%fiestas=("01-01","Inicio de Ao","05-02","Aniversario Constitucion","21-03","Natalicio Benito Jurez","01-05","Da del Trabajo","05-05","Batalla de Puebla","16-09","Da de la Independencia","02-11","Da de muertos","20-11","Revelucin Mexicana","12-12","Da Guadalupe","25-12","Navidad","31-12","Fin de Ao");

Para poder accesar algn elemento, se debe indicar el ndice, dado entre
smbolos de {}.

$fiestas{"16-09"};

El siguiente ejemplo muestra el uso de listas hash.

#!/opt/LWperl/bin/perl

%fiestas=("01-01","Inicio de Ao","05-02","Aniversario Constitucion","21-03","Natalicio Benito Jurez","01-05","Da del Trabajo","05-05","Batalla de Puebla","16-09","Da de la Independencia","02-11","Da de muertos","20-11","Revelucin Mexicana","12-12","Da Guadalupe","25-12","Navidad","31-12","Fin de Ao");



print "Proporciona una fecha (formato dd-MM)\n";

$dia= <STDIN>;
chomp($dia);


if ( $fiestas{$dia} ) {
	print  $fiestas{$dia} 
} 
print "\n";


Existen funciones para manipular listas hash.

La funcin keys proporciona una lista de todos las llaves de una lista hash.

#!/opt/LWperl/bin/perl

%fiestas=("01-01","Inicio de Ao","05-02","Aniversario Constitucion","21-03","Natalicio Benito Jurez","01-05","Da del Trabajo","05-05","Batalla de Puebla","16-09","Da de la Independencia","02-11","Da de muertos","20-11","Revelucin Mexicana","12-12","Da Guadalupe","25-12","Navidad","31-12","Fin de Ao");


foreach $dia (  keys  %fiestas) {
	print $dia,"\n";
}

Este ejemplo arroja los das en desorden.

Para obtener todos los elementos de una lista hash, se puede aplicar la
funcin values.

#!/opt/LWperl/bin/perl

%fiestas=("01-01","Inicio de Ao","05-02","Aniversario Constitucion","21-03","Natalicio Benito Jurez","01-05","Da del Trabajo","05-05","Batalla de Puebla","16-09","Da de la Independencia","02-11","Da de muertos","20-11","Revelucin Mexicana","12-12","Da Guadalupe","25-12","Navidad","31-12","Fin de Ao");


foreach $dia (  values  %fiestas) {
	print $dia,"\n";
}

La funcin each, retorna un par llave-valor. Cada vez que se aplica, recorre
una posicin de la lista hash.

#!/opt/LWperl/bin/perl

%fiestas=("01-01","Inicio de Ao","05-02","Aniversario Constitucion","21-03","Natalicio Benito Jurez","01-05","Da del Trabajo","05-05","Batalla de Puebla","16-09","Da de la Independencia","02-11","Da de muertos","20-11","Revelucin Mexicana","12-12","Da Guadalupe","25-12","Navidad","31-12","Fin de Ao");


while (  ($fecha,$fiesta)=each %fiestas) {
	print $fecha,"\t",$fiesta,"\n";
}

Cuando sea necesario, se puede aplicar una funcin de borrado de un elemento
de una lista hash, con la funcin delete, la cual borra el elemento a partir
de su valor.

#!/opt/LWperl/bin/perl

%fiestas=("01-01","Inicio de Ao","05-02","Aniversario Constitucion","21-03","Natalicio Benito Jurez","01-05","Da del Trabajo","05-05","Batalla de Puebla","16-09","Da de la Independencia","02-11","Da de muertos","20-11","Revelucin Mexicana","12-12","Da Guadalupe","25-12","Navidad","31-12","Fin de Ao");

delete $fiestas{"25-12"}; #borra fiesta de navidad

while (  ($fecha,$fiesta)=each %fiestas) {
	print $fecha,"\t",$fiesta,"\n";
}

Ejercicios.
1. Escribir un programa que lea un conjunto de lneas e imprima una relacin de 
cuantas veces se repite una palabra en ese texto.


+ Entrada, Salida y argumentos.

La entrada de datos se toma de la entrada estndar.
Cuando se asigna a una variable escalar a la entrada estndar, PERL queda
esperando hasta que se proporcione un texto y un enter.
Cuando se asigna un arreglo, PERL se queda esperando hasta que el usuario
proporciones un fin de archivo (ctrl-d).
Cuando en la entrada estndar no hay mas datos, la variable escalar que 
reciba el valor, toma el valor de undef, indefinido.

El siguiente programa lee un archivo y lo imprime a salida estndar.

#!/opt/LWperl/bin/perl


while ( defined($linea=<STDIN>) ) {

	print $linea;
}

Aunque el valor retornado por <STDIN> no sea asignado, se puede utilizar
la variable especial $_

#!/opt/LWperl/bin/perl


while ( <STDIN>)  {

	print $_;
}

De hecho, si print no tiene ningn parmetro, toma el valor de $_.

#!/opt/LWperl/bin/perl


while ( <STDIN>)  {

	print ;
}

Los argumentos de un programa se accesan por medio del arreglo @ARGV.

#!/opt/LWperl/bin/perl

foreach $arg ( @ARGV )  {

	print "$arg ";
}

print "\n";

Las variables de ambiente de un programa se pueden accesar por medio de la
tabla hash ENV.

#!/opt/LWperl/bin/perl

foreach $key ( keys %ENV )  {

	print "$key $ENV{$key}\n";
}

Existe un operador denominado diamante. Su funcin es proporcionar la
entrada de datos de los archivos indicados en la linea de comandos.

#!/opt/LWperl/bin/perl


while (<>) {

	print $_;
}

Al correr este programa, por ejemplo

Ejemplo25.pl *.pl 

lista todos los programas con extensin pl.

Existe una funcin para imprimir, denominada printf. Su formato es una lista
de valores, donde el primer miembro de la lista es el formato a aplicar,
y los demas miembros, los valores del formato.

Por ejemplo

printf "%s %5g","hola",1.23456;

 
printf funciona igual que en lenguaje C.


+ Funciones.

Una funcin en PERL se define de la siguiente forma:

sub nombre_subrutina {
	#bloque
}

El siguiente ejemplo muestra como definir y usar una subrutina:

#!/opt/LWperl/bin/perl

sub di_hola {

	print "hello world\n";
}

di_hola();

Una funcin puede recibir argumentos. Esto lo logra usando la variable
arreglo denominada @_.

#!/opt/LWperl/bin/perl

sub mensaje {

	print "$_[0]\n";
}

mensaje("hola");
mensaje("aun no me voy...");
mensaje("adios");


En PERL, las variables que se definen en cualquier parte se consideran
como variables globales. Pero PERL tambien soporta el concepto de variables
locales. Una variable local slo puede utilizarse en la funcin que la define.
Para poder definir una variable local, se debe utilizar la funcin my, que
recibe una lista de variables locales.

El siguiente ejemplo muestra esto.

#!/opt/LWperl/bin/perl

$var1=1;
$var2=2;
sub funcion {
	my($var1,$var2);

	$var1=$_[0];
	$var2=$_[1];

	print "Variables locales var1=$var1 y var2=$var2\n";
}



print "Variables globales var1=$var1 y var2=$var2\n";
funcion(3,4);
print "Variables globales var1=$var1 y var2=$var2\n";


Se puede observar que las variables globales var1 y var2 no son anulados sus
valores, pero tampoco se pueden referenciar sus valores dentro de la subrutina
funcin.

El siguiente ejemplo resuelve una ecuacin de segundo grado.

#!/opt/LWperl/bin/perl

sub segundogrado {
	my($a,$b,$c,$discriminante,$raiz1,$raiz2,$preal,$pim);

	$a=$_[0];
	$b=$_[1];
	$c=$_[2];

	$discriminante= $b*$b - 4*$a*$c;

	if ($discriminante>=0) {
		$raiz1= (-$b+sqrt($discriminante))/2*$a;	
		$raiz2= (-$b-sqrt($discriminante))/2*$a;	
	} else {
		$preal=(-$b/2*$a);
		$pim=sqrt(-$discriminante)/2*$a;
		$raiz1= "$preal"."+j $pim"; 
		$raiz2= "$preal"."-j $pim"; 
	}

	return $raiz1."\t".$raiz2;
}


print segundogrado(1,2,1)."\n";
print segundogrado(1,1,1)."\n";
print segundogrado(1,0,1)."\n";


Para retornar un valor desde una subrutina, se debe utilizar la instruccion
return.

En PERL se pueden definir variables que son privadas o locales a partir
de un procedimiento.

El siguiente ejemplo muestra esto.

#!/opt/LWperl/bin/perl

$variable="valor global";

dime();
espia();
dime();

sub espia() {
	local($variable)="valor local de espia";
	dime();
}

sub dime() {

	print "Valor es $variable\n";
}

Valor es valor global
Valor es valor local de espia
Valor es valor global

Se puede notar el uso de la funcin local, que recibe una lista de variables
que se declara local en la funcin espia, pero es global con respecto a
las subrutinas que llame la rutina que definio la variable local.

Ejercicio.
1. Escribir un programa en PERL que reciba un nmero y lo retorne en
palabra (por ejemplo 1 debe indicar uno, 9 debe indicar 9). Si el valor
del nmero est fuera de rango, debe retornar al mismo nmero, sin convertirlo.
Utilizar subrutinas y la rutina que convierta de numrico a palabra no
debe capturar datos.
2. Explicar la diferencia entre la subrutina local y my.

+ Expresiones Regulares.

PERL es un lenguaje diseado para extraer datos. Para lograr esto, utiliza
el concepto de expresiones regulares.

Una expresin regular es un patrn que se hace coincidir con una cadena de
caracteres. La operacin de coincidir, consiste en que PERL lee la cadena
de caracteres y la convierte en "tokens", segn caracteres separadores
 indicados en la expresin regular.

Si una coincidencia de una expresin regular cumple  o no la condicin indicada
, se puede tomar alguna accin.

Muchas herramientas de UNIX (grep,sed, awk, vi, emacs) tienen esta filosofa.

Una expresin regular puede utilizarse para buscar una palabra o texto dentro
de una cadena de caracteres.

Por ejemplo, hacer un programa que busque la palabra while en un conjunto
de archivos.

En PERL existe un operador para buscar patrones, denominado / /. Entre ambas
diagonales se encierra la expresion regular.

Para implantar el programa, se utiliza este operador.

#!/opt/LWperl/bin/perl


while (<>) {
	if (/while/) { #si la linea actualmente leida contiene la palabra while
		print ; #la imprime
	}
}

Al correr este programa
Ejemplo32.pl *.pl

Imprime:
while (@lista) {
while (  ($fecha,$fiesta)=each %fiestas) {
while (  ($fecha,$fiesta)=each %fiestas) {
while ( defined($linea=<STDIN>) ) {
while ( <STDIN>)  {
while ( <STDIN>)  {
while (<>) {
while (<STDIN>) {
while (<>) {
        if (/while/) { #si la linea actualmente leida contiene la palabra while
while ($i< @preguntas) {
}while $orden eq @platillos[$i-1] && $i<@platillos;

Que es el resultado de buscar en todos los archivos con extensin pl.

Las expresiones regulares pueden ser mas elaboradas, y a continuacin se
da un ejemplo de algunas:

+ Buscar una linea que termine con los caracteres {\
Expresion regular es /}\n/

#!/opt/LWperl/bin/perl


while (<>) {
	if (/}\n/) {  
		print ; 
	}
}

+ Buscar una linea que contenga el caracter a,b,c,d.
Expresion regular es [abcde] (el operador [ ] indica un solo caracter en
el rango dado)

#!/opt/LWperl/bin/perl


while (<>) {
	if (/[abcde]/) { #si la linea actualmente leida contiene la palabra while
		print ; #la imprime
	}
}
 
+ Buscar una linea que contenga cero o mas caracteres, seguido de la palabra
sh.

Expresion regular es /.*sh/ donde el caracter . indica cualquier caracter,
el * es un caracter comodin que indica junto con el ., cero o mas caracteres
de cualquier tipo, seguido de la palabra sh.

#!/opt/LWperl/bin/perl


while (<>) {
	if (/.*sh/) { 
		print ; #la imprime
	}
}

 
Se puede corre este ejemplo como:
ps -ef | Ejemplo35.pl

+ Buscar una linea vacia. Una linea vacia es aquella que tiene el inicio de linea,  un salto de carro y el fin de la linea.

Expresin regular --> /^\n$/ 
El caracter ^ indica inicio de linea y $ fin de linea

#!/opt/LWperl/bin/perl


while (<>) {
	if (/^\n$/) { 
		print ; #la imprime
	}
}

+ Buscar lineas con dgitos
Expresion regular --> /[0-9]/ o /\d/ donde \d se interpreta como digito.

#!/opt/LWperl/bin/perl


while (<>) {
	if (/\d/) { 
		print ; #la imprime
	}
}

Otras abreviaturas similares a \d son:
\w abrevia [a-zA-Z0-9_] (un caracter de una palabra)
\s abrevia [ \r\n\t\f] (caracteres de espacio).

+ Buscar lineas sin dgitos.

Expresion regular --> /[^0-9]/ o /\D/ donde \d se interpreta como no digito.
El caracter ^, dentro del operador [] se interpreta como una negacin .

#!/opt/LWperl/bin/perl


while (<>) {
	if (/\D/) { 
		print ; #la imprime
	}
}


Los patrones de una expresin regular pueden agruparse.
Estas son las agrupaciones:

+) Secuencia.
Un patron seguido de otro patron.
Por ejemplo /while/ se interpreta como el caracter w, seguido de h, seguido de
i.

Por ejemplo, se puede pedir un patron que indique, inicio de linea, seguido
de cualquier caracter que no sea espacio. (/^\S/)

#!/opt/LWperl/bin/perl


while (<>) {
	if (/^\S/) { 
		print ; #la imprime
	}
}


+) Multiplicadores o mltiplos.
Permiten agrupar patrones que se repiten varias veces.

El comodn * indica cero o mas veces. Por ejemplo buscar un texto donde
aparezca la letra l seguida de e cero o mas veces (l puede estar vacio)
/le*/

#!/opt/LWperl/bin/perl


while (<>) {
	if (/le*/) { 
		print ; #la imprime
	}
}

Pero si se requiere exactamente de uno o mas caracteres e, se utiliza
el comodn +.

#!/opt/LWperl/bin/perl


while (<>) {
	if (/le+/) { 
		print ; #la imprime
	}
}

+) Alternativas.

Buscar un patron u otro.

Por ejemplo, buscar la palabra while, do o for.

#!/opt/LWperl/bin/perl


while (<>) {
	if (/\s*(while|do|for)\s+/) { 
		print ; #la imprime
	}
}

Con PERL se puede aplicar la operacin de sustitucin.

Por ejemplo, si se desea sustituir la palabra while por mientras.

#!/opt/LWperl/bin/perl


while (<>) {

	s/while/mientras/g;
	print $_;
}


Aqu se aplica la operacion s (sustituir) sobre la variable $_ y cuando
encuentra alguna ocurrencia de while, sustituye TODAS las ocurrencias por
la palabra mientras.


Existen funciones que permiten dividir una linea de texto en tokens.
Esta funcin es split, que recibe una lnea de texto y el caracter separador
de los tokens, y retorna un arreglo con cada token.

El siguiente ejemplo lee el archivo /etc/passwd y lo separa por campos:

#!/opt/LWperl/bin/perl


while (<>) {

	@campos=split(/:/,$_);
	print "@campos";
}


Ejemplo44.pl /etc/passwd

Se puede tomar una lsita de PERL y unirla en una linea, separada por
un caracter.

#!/opt/LWperl/bin/perl


while (<>) {

	@campos=split(/:/,$_);

	$linea= join("\n",@campos);
	print "$linea\n";
}


Ejemplo45.pl /etc/passwd

El siguiente ejemplo recibe una variable de ambiente con el siguiente formato:

nombre1=valor&nombre2=valor

donde valor contiene una cadena de caracteres, si se encuentra un signo
de +, se debe sustituir por espacio.

Lo lee de la variable QUERY_STRING

#!/opt/LWperl/bin/perl

$query_string= $ENV{"QUERY_STRING"};

if ( !defined($query_string)) {

	print "Indicar variable ambiente QUERY_STRING\n";
}

@pares=split(/&/,$query_string);

foreach $par (@pares) {

	($nombre,$valor)=split(/=/,$par);
	$valor=~s/\+/ /g;
	print "$nombre $valor\n";
}

Este ltimo ejemplo es el principio elemental para procesar CGI.



El siguiente ejemplo obtiene, a partir de la tabla de procesos, la
lista de todos los procesos hijos de un PID dado


#!/opt/LWperl/bin/perl

if (!@ARGV) {
	print "Ejemplo47 pid\n";
} else {
$padre=$ARGV[0];
$i=0;

while (<STDIN>) {

	/^(\W+)(\w+)(\W*)(\w+)(\W*)(\w+)/;

	$ppid=$6; #obtener pid del padre
	$pid=$4;

	if ( $ppid == $padre) {
		$hijos[$i]=$pid;
		$i++;
	}
}

print "Procesos hijos son: @hijos\n";
}

ps -ef | Ejemplo47.pl 1

Existe un operador denominado =~, cuya funcin es aplicar las operaciones
de busqueda o sustitucin sobre una variable diferente a $_.

Cuando se utiliza para busqueda, se indica la variable que contiene el
texto y la expresin regular

$texto=~/expresion/

esta operacin regresa un verdadero o falso.

#!/opt/LWperl/bin/perl

$texto="ser o no ser, he ahi el dilema";

if (  $texto=~/ser/) { #aplica operador =~ para buscar
	print "Encontre la palabra ser\n";
}

$texto=~ s/ser/to be/g; #aplica la sustitucion

print "$texto\n";

$texto=~ tr/[a-z]/[A-Z]/; #aplica traduccion
print "$texto\n";


El siguiente programa lee la tabla de procesos e imprime el programa y
su id de proceso.

#!/opt/LWperl/bin/perl

while (<STDIN>) {

	@arreglo=split(' ',$_);

	print "$arreglo[7] $arreglo[1]\n";
}



Y este programa se puede modificar para imprimir solo los procesos de root



#!/opt/LWperl/bin/perl

while (<STDIN>) {

	@arreglo=split(' ',$_);

	if ($arreglo[0] eq "root") {
		print "$arreglo[7] $arreglo[1]\n";
	}
}


Ejercicio.

1. Escribir un programa que tome la salida del comando who y busque el usuario
especificado.
2. Escriba un programa que de la direccion IP de una maquina, dando el nombre
con el que se conoce en /etc/hosts.
3. Explicar el siguiente programa.

#!/opt/LWperl/bin/perl

$i=0;

while (<>) {

	s/^/$i:\t/;
	print;
	$i++;
}


Ejercicios

Buscar PERL para Windows 95 o NT, bajarlo, instalarlo y tratar de
probar algunos ejemplos de este captulo.
