Tutorial de Perl
Tutorial de Perl
1. Introducción al Perl.
2. La sintaxis de Perl.
3. Tipos de datos.
4. Operadores.
5. Estructuras de control.
6. Expresiones regulares.
7. Creación de funciones.
8. Entrada / salida.
9. Variables predefinidas.
1
Introducción al Perl
1. ¿Qué es Perl?
Perl (Practical Extraction and Report Languaje) es un lenguaje creado a principio de los noventa por Larry
Wall, el cual lo realizó casi como una obra altruista, por eso, su distribución es gratuita.
Perl es un lenguaje pensado para la manipulación de cadenas de caracteres, archivos y procesos. Esta
manipulación se va simplificada por el importante número de operadores a disposición del usuario. El
lenguaje Perl se percibe habitualmente como un lenguaje intermedio entre los shell scripts y la programación
en C. En efecto, los programas en Perl son una sucesión de instrucciones y son similares a los shell scripts
porque no existe un procedimiento principal como la subrutina main en C. Sin embargo, se parece al lenguaje
C en su sintaxis y en el número importante de funciones que permiten la manipulación de cadenas de
caracteres y archivos.
El lenguaje Perl no es precompilado, pero aún así es más rápido que la mayoria de lenguajes interpretados, en
especial que el Bourne Shell. Esto se debe a que los programas en Perl son analizados, interpretados y
compilados por el interprete perl antes de su ejecución.
Estas características hacen que el mantenimiento y la depuración de un programa en Perl sean mucho más
sencilla que el mismo programa escrito en C.
Por todo esto, Perl es un lenguaje muy utilizado en los dos campos siguientes:
2
La sintaxis de Perl
1. Un lenguaje interpretado.
Como sabemos Perl es un lenguaje interpretado, en consecuencia para ejecutar un script en Perl debemos
indicarle al sistema en ese mismo instante el interprete que vamos a utilizar para ejecutar dicha script en Perl.
Esto se puede realizar de dos formas:
Así sólo nos queda saber que para ejecutar un script, el fichero que lo contiene en este caso script.pl debe
tener permiso de ejecución al menos sólo desde el punto de vista del usuario. Para saber los permisos que
contiene un fichero en el sistema operativo Unix basta simplemente con teclear el siguiente comando: ls -l.
Si cuando tecleamos esto y vemos que no tiene permiso de ejecución, utilizaremos el siguiente comando para
darle dicho permiso: chmod 700 script.pl.
De esta manera, sólo podremos leer, escribir y ejecutar el archivo nosotros como usuarios del mismo.
2. El intérprete de Perl.
Como ya hemos dicho en el capítulo anterior, una de las maneras de ejecutar un script de Perl era ejecutando
dicho script como un parámetro de un interprete de Perl determinado. Pues bien, dicho intérprete posee
ciertas opciones que nos proporcionan o bien información sobre el mismo, o bien ciertas facilidades a la hora
de ejecutar los script como se podrá ver a continuación.
perl -v : Muestra la versión del intérprete de Perl que estamos utilizando.
perl -V : Muestra información sobre la configuración del intérprete de perl.
perl -e expresión : Ejecuta la expresión como si ésta fuera un programa de una línea. Por ejemplo:
perl -e "print 'hola a todos\n';"
perl -ne expresión : Ejecuta la expresión como si está fuera un bucle repetitivo. He aquí un ejemplo:
perl -ne "print if /M+/;" usuarios.txt . Este ejemplo extrae todos los usuarios cuyo nombre empieze
por la letra M.
perl -d script : Ejecuta el script bajo el depurador.
perl -w script : Da avisos sobre las contrucciones con errores.
perl -pe expresión : Ejecuta la expresión como si está fuera un bucle repetitivo y además imprime
cada línea. He aquí un ejemplo: perl -pe "print if /M+/;" usuarios.txt . Observar diferencia con la
opción -ne. La diferencia es que mientras la primera versión sólo imprimía los nombres que
empezaban por M, la segunda por su parte imprimía todos los nombre una vez salvo los que empiezan
por M que los imprime dos veces.
perl -x script : Empieza a interpretar el fichero que contiene el script cuando encuentra la referencia
al intérprete, por ejemplo: #!/usr/bin/perl.
3
perl -i archivo : Permite editar archivos. Por ejemplo, si ejecutamos lo siguiente sobre la línea de
comandos: perl -p -i -e "s/\$seg/\$segundos/g;" tiempo.pl. Esta orden cambiará el nombre de la
variable $seg por $segundos en el script contenido en el fichero tiempo.pl.
#!/usr/local/bin/perl
print "¡Hola, mundo!";
Una vez que hayamos verificado los permisos de dicho script estaremos listos para ejecutarlo simplemente
tecleando en la línea de comandos: hola.pl.
Por último hacer notar que lo de la extensión .pl es simplemente una formalidad y que nos es absolutamente
necesario que el fichero que contenga nuestro script lleve dicha notación.
$x = 0.897; # un real
$y = 6.23e-24; # un real
$n = 567; # un entero
$i = -234; # un entero
Nota: El que todas las variables contengan un $ significan que representan un escalar. Esto lo
veremos en el siguiente apartado.
Los valores enteros no pueden empezar por cero porque esto permite especificar un entero
mediante su codificación octal o hexadecimal. El código octal se antecede con en cero 0; el
código hexadecimal se antecede con un 0x o 0X. Por ejemplo:
4
1.2. Las cadenas de caracteres.
Las cadenas de caracteres se especifican literalmente por medio de un sucesión de caracteres
delimitada por comillas ("..") o apóstrofes ('..'). Estas dos representaciones se distinguen por la
interpretación hecha por Perl de las cadenas de caracteres. Cuando van delimitadas por
comillas (".."), toda variable referenciada en el interior de la cadena se evalúa y se reemplaza
por su valor. Por ejemplo, las instruciones siguientes:
$wld = "mundo";
$str = "¡Hola $wld!";
asignan al escalar la cadena de caracteres "¡Hola mundo!". Por el contrario, las cadenas de
caracteres delimitadas por apóstrofes se dejan intactas. Por ejemplo:
$str = <<etiqueta;
....
etiqueta
donde la etiqueta es una cadena de caracteres cualquiera. El fin de la cadena se determina por
la nueva línea que contiene únicamente el identificador. Éste no debe ir precedido por un
espacio ni marca de tabulación. Por ejemplo:
$msg = <<SALUDO;
hola,
buenos días,
adios,
SALUDO
Estas tres representaciones permiten asociar a cada variable utilizada un tipo. Por otra parte, las variables Perl
no tienen que declararse antes de su uso. Se asignan de manera dinámica y se les asigna un valor
predeterminado en función del contexto.
5
2.1. Los escalares.
El escalar representa el tipo básico en Perl. Permite representar enteros, reales y cadenas de
caracteres. Las variables de tipo escalar van precedidas por el símbolo $. A continuación
veremos algunos ejemplos:
$real = 4.53;
$entero = -45;
$ristra = "Hola";
Las variables en Perl se asignan de manera dinámica y se les asigna un valor predeterminado
en función del contexto. En un contexto numérico el valor predeterminado es 0, mientras que
en un contexto de cadena de caracteres el valor predeterminado es la cadena vacía "".
Como ya hemos dicho, cuando una cadena de caracteres se delimita por comillas, el contenido
de esta cadena es analizado por Perl para el reemplazo eventual por su valor de las variables
escalares identificadas por el símbolo $. Este análisis se denomina interopolación de variables
y puede evitarse poniendo delante del símbolo $ una barra oblicua inversa \ o delimitando la
cadena de caracteres con apóstrofes. He aquí un ejemplo:
$adr = "www";
$msg = "El servidor web ${adr}.ulpgc.es"; print $msg, "\n";
$msg = "El servidor web $adr.ulpgc.es"; print $msg, "\n";
$msg = "El servidor web \$adr.ulpgc.es"; print $msg, "\n";
$msg = 'El servidor web $adr.ulpgc.es'; print $msg, "\n";
Observe la contrucción ${...} para referenciar el nombre de una variable en una cadena de
caracteres. Si lo hubieramos omitido, el ejemplo anterior habría hecho referencia a la variable
$adr.ulpgc.es no definida.
El tipo y el valor de las variables en Perl se determina a partir del contexto. Así, una cadena de
caracteres conteniendo un valor numérico será convertida en variable numérica en un contexto
numérico. Consideremos el código siguiente:
$x = 4.1; # un real
$y = "11"; # una cadena de caracteres
$z = $x + $y; # adición de dos valores numéricos
$t = $x . $y; # concatenación de dos cadenas
print $z, "\n", "$t \n";
Al final del código la variable $z tiene el valor 15.1. Por otro lado, la variable $t contiene el
valor "4.111". Por lo tanto en Perl no es necesario realizar una declaración de tipos, ni es
necesario el operador cast, ni tampoco es necesario dar formato a los valores a la hora de
imprimirlos como ocurría en C. Esta interpolación se produce a menudo en unas líneas de
código tales como las siguientes:
$year = 35;
print "Tengo $year años";
El resultado de estas líneas de código es: "Tengo 35 años"; el contenido de la variable year se
ha convertido en una cadena de caracteres.
2.2. Los arrays.
6
Un array es una lista de datos de tipo escalar. Cada elemento de la lista es una variable escalar
a la que se le asocia un valor. Las variables de tipo array se identifican por el prefijo arroba @.
Por ejemplo:
También se permite definir los elementos de un array a partir de sus valores extremos como se
muestra a continuación:
@alfabeto = (a..z);
También se puede acceder a un array mediante el operador que define una horquilla de
índices. Por ejemplo:
Esta última instrucción vemos que permite asignar los dos primeros valores del array
@mezcla a las variables escalares $ristra y $num. Por otro lado, el acceso a un array fuera de
rango devuelve un valor indefinido 0 o "" según el contexto.
Por último, si vemos las siguientes líneas de código:
@a=(1,2,3);
@b=(5,6,7);
@c=(@a,4,@b,8);
Estas expresiones generan tres arrays, (1,2,3), (5,6,7) y (1,2,3,4,5,6,7,8), y no, como podría
pensarse un array de arrays, cuando incluimos un array dentro de otro, Perl "aplana" el array
insertado uno a uno todos sus elementos en la posición indicada del array que ha de
contenerlos, para hacer array de arrays deberemos usar referencias a estos. Como veremos en
el apartado 4 de este capítulo.
7
En este caso, para acceder a cualquiera de los elementos de %cuota debemos conocer su
clave. Por ejemplo:
Esta lista puede completarse añadiendo nuevos valores y asociando a cada clave el valor
correspondiente. Por ejemplo:
$cuota{"dave"} = 250;
$rescalar = \$escalar;
$rarreglo = \@arreglo;
$rhash = \%hash;
Por otro lado, cuando usamos el operador de referenciación con un valor, creamos objetos
anónimos que sólo pueden ser accedidos por medio de la referencia.
8
%rNumeros = {"arabes" => [1,2,3], "romanos" => [I, V, X]}
El ejemplo que acabamos de ver forma una lista asociativa anónima donde las claves son
cadenas de caracteres y los valores son referencia a arrays.
$nombre="entero";
$entero=5;
$rentero=\$entero;
$$nombre=6;
$$rentero=7;
Como forma de abreviar la referencia a listas asociativas o arrays se añadió en operador "->".
A continuación veremos un ejemplo de uso del mismo.
$rarray->[2]="hola";
# Coloca "hola" como 3º elemento del array referenciado
$rlista->["clave1"]="valor1";
# Coloca el par ("clave1" => "valor1")
Se pueden realizar referencias a referencias y arreglos a referencias de forma que los arryas
multidimensionales se pueden hacer con la misma facilidad que en C. Ejemplo:
$array3d->[0]->[0]->[0]=1;
# Forma abreviada:
$array3d[0][0][0]=1;
# También se puede usar
$array3d->[0][0][0]=1;
9
En Perl distinguiremos tres tipos de operadores dependiendo de la representación de datos sobre la que
queremos actuar. De este manera habrá tres tipos de operadores: los operadores asociados a los escalares, los
asociados a los arrays y por último, los vinculados a las listas asociativas.
$n = $k++;
# el valor de k se asigna a n y después se incrementa k
$n = ++$k;
# primero se incrementa k y luego se asigna a n
Finalmente, decir que con el operador de decremento se actúa de forma análoga obteniendo
así el predecremento y el postdecremento.
10
Perl distingue dos tipos de operadores relacionales: los operadores específicos a valores
numéricos y los propios de las cadenas de caracteres. Estos operadores se resumen en la
siguiente tabla:
A parte de los operadores que hay en la tabla cabe distinguir otros operadores únicamente
característicos del lenguaje Perl.
if ($ristra =~ /str/) {
print $ristra;
}
else {
print "No se encuentra el patrón";
}
# verifica si 'str' se está en $ristra
if ($ristra !~ /str/) {
print "No se encuentra el patrón";
}
else {
11
print $ristra;
}
He aquí un ejemplo:
12
A parte de estos operadores Perl posee el operador =~ que también es un operador de
asignación, ya que este operador se utiliza dentro de una expresión regular de sustitución para
sustituir un patrón de comparación por otra cadena. Ejemplo:
$var =~ s/uno/dos/;
# reemplaza la primera ocurrecia "uno" por "dos" en
# la cadena dada
13
Además en Perl tenomos los símbolos de puntuación que a diferencia de otros lenguajes son
considerados operadores en Perl. Básicamente tenemos cuatro símbolos que nos permiten
agrupar otros símbolos para darles una interpretación especial.
' '. Especifica valores literales. No hace sustituciones. Ejemplo:
if ($var =~/exe/) {
print $var;
}
# Se imprime $var si contiene el patrón exe
14
Perl posee una serie de funciones predefinidas que nos facilitan el tratamiento de cadenas de
caracteres. Si ellas, realizar operaciones con este tipo de datos sería casi imposible. A
continuación nombraremos las funciones básicas para efectuar dicho tratamiento:
$ristra = "hola";
lon = length($ristra); # lon = 2
rindex(ristra, subristra, [posición]). Esta posición trabaja igual que index salvo que
retorna de la última ocurrencia de la subristra en la ristra. Posición es el número de
caracteres desde el inicio que se ignorá en la búsqueda. Si no se encuentra posición, el
valor retornado es posición menos 1. Ejemplo:
15
$subristra = substr($ristra,15);
# $subristra = "Las Palmas de G.C."
$StringForm =~ s/\%(..)/pack("c",hex($1))/ge;
El operador $# permite delimitar el último índice válido de un array. Este valor norepresenta
el tamaño del array, porque esto depende también del índice de base (es decir, el primer
elemento del array). Esto se define por la variable $[ cuyo valor predeterminado es 0.
Mediante estos dos elementos se puede delimitar el tamaño del array. Por ejemplo, si @A es
un array, el código siguiente permite determinar su tamaño:
16
$n = $#A - $[ + 1;
print "La matriz tiene $n elementos\n";
@five = (2,3,4,5,1);
sort(@five); # @five = (1,2,3,4,5)
reverse(@five); # @five = (5,4,3,2,1)
17
donde se representa una expresión regular cualquiera. Por ejemplo:
$datos = "x=3&dbase=Lycos";
@lista = split(/&/, $datos);
foreach $par (@lista) {
($nombre, $valor) = split(/=/, $par);
}
Por último, el tercer parámetro consiste en un campo entero que limita el número de campos
que divide la lista de caracteres, despreciando los sobrantes, por ejemplo si en él código que
acabamos de ver no queremos el campo representado en la variable valor, realizaremos los
siguientes cambios.
$datos = "x=3&dbase=Lycos";
@lista = split(/&/, $datos);
foreach $par (@lista) {
$nombre = split(/=/, $par,1);
}
El operador join realiza la tarea inversa. Así, a partir de un serparador de un lista de valores,
concatena los elementos de la lista y la cadena de caracteres que representa el separador. La
sintaxis del operador join es la siguiente:
El operador keys proporciona la lista de claves o índice de una lista asociativa. Por ejemplo:
Estructuras de control
El desarrollo de un programa viene determinado por el orden en que aparecen las instrucciones. El lenguaje
Perl posee controlar un conjunto de instrucciones que permiten controlar el desarrollo de un programa. Estas
instrucciones se denominan estructuras de control porque permiten ejecutar un conjunto de instrucciones
cuando se verifica una condición o ejecutar iterativamente un bloque de instrucciones mientras una expresión
sea válida.
1. La instrucción if.
Es muy parecida a la utilizada en C. La sintaxis de la instrucción if es la siguiente:
if (expresión) {
instrucción o bloque de intrucciones 1;
}
[else {
instrucción o bloque de intrucciones 2;
}]
El programa evalúa la expresión. Cuando esta expresión resulta verdadera, se ejecuta la instrucción o el
bloque de instrucciones 1. Por contra, cuando es falsa de ejecuta la instrucción o bloque de instrucciones 2.
Esta última parte es opcional. Para representar una estructura de varios casos se utilizará la sintaxis siguiente:
if (expresión 1) {
instrucción o bloque de instrucciones 1;
}
elsif (expresión 2) {
instrucción o bloque de instrucciones 2;
}
elsif (expresión 3) {
instrucción o bloque de instrucciones 3;
}
else {
intrucción o bloque de instrucciones 4;
}
19
A continuación veremos un ejemplo sencillo del uso de esta estructura para comprender mejor su
funcionamiento:
2. La instrucción while.
La instrucción while ejecuta iterativamente un bloque de instrucciones mientras una expresión sea válida,
evaluando la comprobación en cada iteración. Cuando la prueba es válida, se ejecuta la instrucción o el
bloque de instrucciones delimitado por las llaves. La sintaxis de esta instrucción es:
while (expresión) {
instrucción o bloque de instrucciones;
}
3. La instrucción for.
La instrucción for permite ejecutar iterativamente un conjunto de instrucciones. La sintaxis de la instrucción
for es:
donde:
inicial_exp es la instrucción que inicializa el bucle. Consiste generalmente en la asignación de un
valor a una variable que permite controlar el número de iteraciones.
20
test_exp es la expresión evaluada en cada iteración. Cuando esta expresión es verdadera, el bloque de
instrucciones se ejecuta.
incremento_exp es la expresión que permite la actualización de la variable que controla el número de
iteraciones.
4. La instrucción foreach.
La instrucción foreach es similar a la función del mismo nombre de los Shells de Unix. Asocia iterativamente
a una variable cada elemento de la lista. Esta sucesión de valores sirve para parametrizar la ejecución del
bloque de instrucción. La sintaxis de la instrucción foreach es:
Las intrucciones for y foreach son equivalentes. Sin embargo, la utilización de una de estas instrucciones se
justifica generalmente por el contexto. El ejemplo siguiente lo ilustra:
Este ejemplo no utiliza las características de los arrays en Perl. La utilización de la instrucción foreach
permitirá recorrer la lista de forma más elegante. El ejemplo siguiente lo ilustra:
5. La instrucción goto.
La instrucción goto label permite cambiar el recorrido lineal de las líneas de código prosiguiendo la
ejecución del programa en la línea de etiqueta label. La etiqueta se define colocando al final del identificador
dos puntos (:). En el siguiente ejemplo se podrá ver mejor la contrucción del goto.
if ($expr ne $expr_correcta) {
goto error;
}
...
error: print "expresión incorrecta";
21
La utilización del goto en Perl no es recomendable. Por que le quita al código legibilidad y aumenta la
posibilidad de errores.
6. La instrucción last.
La instrucción last interrumpe la ejecución del bucle actual y se ejecuta la instrucción que sigue al bloque. El
ejemplo siguiente permite interrumpir el bucle while cuando la variable i toma el valor 3.
$i = 0;
while($i < 6) {
if($i == 3) {
last;
}
$i++;
}
print "el valor de \$i es $i";
Cuando la instrucción tiene como argumento una etiqueta, la ejecución prosigue en la línea indicada por la
etiqueta.
7. La instrucción next.
La instrucción next es idéntica a la instrucción continue en C. Interrumpe la ejecución del bloque de
instrucción actual y prosigue la ejecución en la iteración siguente. Esta instrucción no interrumpe
completamente la ejecución del bucle; la expresión que controla el bucle se evalúa. Si el resultado de la
expresión es válido, el bucle se ejecuta de nuevo.
Cuando una instrucción tiene como argumento una etiqueta, la instrucción prosigue en la línea identificada
por la etiqueta y no al principio del bloque.
Seguidamente veremos un ejemplo de dicha instrucción:
8. La instrucción until.
La instrucción until al igual que la instrucción while permite ejecutar un conjunto de instrucciones un número
repetido de veces. Pero al contrario que la la instrucción while, la intrucción until ejecuta dicho bloque de
instrucciones mientras no se verifique la comprobación. La sintaxis es:
until (expresión) {
instrucción o bloque de instrucciones;
}
22
print "Teclea \"x\" para salir:\n";
print "Si se pulsa la tecla \"s\" no se imprime:\n";
$ristra = "";
until ($ristra eq "x") {
$ristra = ; chop($ristra);
if ($ristra eq "s") {
next;
}
print "Has escrito $ristra\n";
}
print "Salida.\n"
9. La instrucción unless.
Esta instrucción es análoga al if, salvo que permite considerar la no verificación de la prueba. Su sintaxis es
la siguiente:
unless (expresión) {
instrucción o bloque de intrucciones 1;
}
Para ver mejor el funcionamiento del unless, modificaremos el ejemplo anterior para adaptarlo a dicha
instrucción.
Expresiones regulares
Una expresión regular es un modelo o una forma de comparar con una cadena de caracteres. Esta
comparación es conocida con el nombre de pattern matching o reconocimiento de patrones, permite
identificar las ocurrencias del modelo en los datos tratados. La utilización principal de las expresiones
regulares en Perl consiste en la identificación de cadenas de caracteres para la búsqueda modificación y
extracción de palabras clave. De esta manera se pueden dividir las expresiones regulares en varios tipos que
son: expresiones regulares de sustitución, expresiones regulares de comparación y expresiones regulares de
traducción.
23
1. Expresiones regulares de comparación.
Nos permiten evaluar si un patrón de búsqueda se encuentra en una cadena de caracteres, de modo que
mediante este tipo de expresiones regulares obtendremos un valor lógico verdadero o falso según se
encuentre el patrón deseado. La sintaxis de este tipo de expresiones regulares es la siguiente:
valor a comparar =~ patrón de búsqueda
He aquí un ejemplo:
Los patrones de búsqueda pueden integrar información relativa al contexto, tal como la búsqueda de líneas
que empiecen por la cadena de caracteres, la extracción de palabras que tengan prefijos o sufijos
particulares... Estos contextos se tienen mediante una representación particular del modelo. Esta
representación se explica en los siguientes apartados:
A menudo resulta práctico extraer las palabras que contienen una cifra, una vocal, o caracteres
de control particulares. El modelo así definido no se indica por un carácter particular sino por
un clase de caracteres mediante el operador [ ]. He aquí algunas posibles construcciones:
La definición del patrón por clase se contempla con un conjunto de caracteres de control.
Estos facilitan la definición de modelos complejos en rutinas de comparación. Estos facilitan
la definición de patrones complejos en rutinas de comparación. La siguiente tabla representa
estas extenciones:
24
Por otro lado, decir que los símbolos \n, \r, \f y \t tienen su significado habitual, es decir,
significan nueva línea, retorno de carro, salto de página y tabulación respectivamente.
A continuación veremos otra lista de caracteres genéricos que aumentarán la flexibilidad en la
contrucción de patrones de búsqueda. Estos caracteres se muestran en la siguiente tabla:
$var = "coche";
$var =~ s/(coche)/El $1/; # $1 equivale a coche
print $var;
\1,\2,...,\9. Este operador tiene la misma utilidad que el anterior se utiliza para
referenciar patrones, pero esta vez la referencia se ha de producir dentro de la
expresión regular. He aquí un ejemplo:
if ($var =~ (/^(\w)+.*\1$/) {
print $var;
}
25
será cierto, ya que los espacios en blanco no se consideran caracteres
alfanuméricos.
1.3. Utilización de carácteres reservados.
En la especificación del modelo, cada carácter se interpreta para determinar las ocurrencias en
los datos. Sin embargo, los caracteres siguientes:
+?.*^$()[]{}|&\
son reservados por el lenguaje y deben ir precedidos por el símbolo de barra inversa \. Esto
permita ignorar su especificidad y considerar los como un carácter cualquiera. Por ejemplo:
mientras que con el operador & exigimos que la variable contenga las dos expresiones
regulares propuestas:
26
$var = 'abc123yz';
$var =~ s/d+/$&*2/e; # $var = 'abc246yz'
$var =~ s/d+/sprintf("%5d",$&)/e; # $var = 'abc 246yz'
$var =~ s/\w/$& x 2/eg; # $var = 'aabbccc 224466yyzz'
Nota: Como veremos en el capítulo 10 con más profundidad, $& es una variable predefinida por el lenguaje que
contiene el valor de la última cadena de caracteres comparada exitosamente.
También decir que este operador devuelve el número de reemplazados o borrados. He aquí algunos ejemplos
que nos servirán para tener una manejo:
4. Ejemplo.
Seguro que ha estas alturas todavía no se tiene claro la diferencia entre los distintos tipos de expresiones
regulares, para aclarar el concepto introducimos los siguientes ejemplos:
En primer lugar vemos una expresión regular de búsqueda que dará cierto si en la variable $copia se
encuentra el patroón copia. Si es así, como veremos se imprimirá un mensaje.
Esta operación reemplaza todas las ocurrencias de copy por copia quedando:
"copia, xcopia, diskcopia"
En último lugar realizaremos un ejemplo con una expresión regular de traducción:
27
$copia = "copy, xcopy, diskcopy";
$copia =~ tr/copy/12345/;
Como se ve en este caso, se sustituye cade ocurrecia de 'c' por 1, de 'o' por 2, de 'p' por 3 y de 'y' por 4. El
carácter de traducción 5 es ignorado puesto que no tiene ninguna correspondencia con ninguno de los
caracteres de patrón. Por tanto, el contenido de la variable $copia será:
"1234, x1234, disk1234"
Otro caso podría ser el siguiente:
Este ejemplo es idéntico a el anterior pero en este caso sólo tenemos dos caracteres en la cadena de
traducción. Así, cuando el número de caracteres en la cadena de traducción es menor que el número de
caracteres del patrón, las ocurrencia de los caracteres del patrón que no tienen correspondencia con ningún
caracter de traducción, son intercambiados por el último de los caracteres de traducción. Por tanto, el
contenido de la variable $copia será:
"1233, x1233, disk1233"
Definición de funciones
La definición de funciones permite asociar un nombre a un conjunto de instrucciones Perl. La sintaxis para la
definición de función es:
sub nombre_de_función {
instrucciones;
[return Variable o expresión;]
}
& nombre_de_función;
do nombre_de_función();
Las dos formas producen el mismo resultado con la excepción de que en el caso de do hay siempre que poner
los paréntesis. Una llamada a una función puede insertarse en las estructuras y operadores en Perl.
El valor devuelto por la llamada a una función corresponde al valor precisado por el operador return. Cuando
este está ausente, el resultado de la última instrucción corresponde al resultado de la última instrucción
ejecutada en el cuerpo de la función. Por ejemplo:
sub diferencia {
if ($x < $y) {
print "$x es inferior a $y\n";
$y-$x;
}
28
else {
print "$x es superior o igual a $y\n";
$x-$y;
}
}
$x = 2; $y = 3;
$abs = &diferencia; # $abs = 1
En este ejemplo, la función visualiza un mensaje y devuelve el valor absoluto de la diferencia de $x y $y.
Permutando las instrucciones de visualización y de cálculo, la función devolverá 1, valor correspondiente a
una visualización correcta.
Los argumentos de una función.
Al llamar a una función cuando esta va seguida de una lista de variables, éstas últimas se consideran como
sus argumentos. El lenguaje Perl duplica el contenido de estas variables en la variable predefinida @_
durante la ejecución de la función. La variable @_ permite así acceder a los parámetros de la función. Estos
se colocan en la matriz $_[0], $_[1], ..., $_[n-1] referenciando los diferentes argumentos de la función. Por
ejemplo.
sub diferencia {
if ($_[0] < $_[1]) {
$_[1]-$_[0];
}
else {
$_[0]-$_[1];
}
}
$abs = &diferencia(2,3); # $abs = 1
sub producto {
local($p) = 1;
foreach $_(@_) {
$p *= $_;
}
}
$p = 3;
print &producto(2,3,4); # visualiza 24
print "$p\n"; # visualiza 3
29
Es aconsejable asignar a las variables locales los argumentos pasados a la función. Esto permite una mejor
legibilidad de las funciones. Esto se realiza combinando el operador local con la variable predefinida @_.
Por ejemplo:
sub Area_cuadrado {
local($radio) = @_;
return $radio*$radio; # el return sobra
}
sub swap {
local(*x, *y) = @_; # asignación local de los argumentos
local($t); # variable local
$t = $x;
$x = $y;
$y = $t;
return @_; # resultado de la función
}
$a = 4; $b = 1;
&swap(*a, *b); # $a =1; $b = 4;
Resulta esencial que la asignación de los argumentos a las variables locales se haga mediante el operador
local. Ya que la asignación directa de la variable local mediante *nombre=valor modifica las ocurrencias de
la variable nombre en el script. Por ejemplo:
sub swap {
(*a, *b) = @_; # asignación de argumentos
local($t);
$t = $a;
$a = $b;
$b = $t;
return @_;
}
$a = 4; $b = 1;
$x = "pi"; $y = 1.414;
&swap(*x, *y); # $x = 1.414; $y = "pi"
print "a=$a, b=$b\n"; # $a = 1.414; $b = "pi"
Entrada / Salida
30
Perl interactúa con el usuario o con el sistema operativo por medio de entradas salidas que permiten el
intercambio de información. Este intercambio de datos se gestiona por medio de operadores específicos que
configuran una interfaz entre el script y su entorno.
El argumento de open que representa el nombre de archivo puede tener cualquiera de los prefijos que se
muestran en la siguiente tabla, estos prefijos indican el modo de acceso al archivo (si no se pone ningún
prefijo es que se toma el modo de acceso por defecto que es el de lectura):
En cuanto a los punteros a archivos decir que, cuando se ejecuta un programa en Perl su primera actividad es
asignar un puntero o manejador de archivo para el canal de entrada, otro para el canal de salida y otro para el
de información de errores. Estos punteros son respectivamente STDIN, STDOUT y STDERR, donde se
puede observar que STD significa estándar. Los tres STD se usan con tanta frecuencia en Perl que a menudo
se suponen que existen, y por consiguiente, Perl no necesita que se mencionen explícitamente, en lugar de
ello, Perl los crea y les asigna canales automáticamente. Por ejemplo:
print "hola";
print STDOUT "hola";
Estas dos líneas realizan lo mismo ya que Perl supone que STDOUT es el monitor y por eso visualiza sin
necesidad de indicar en ningún lugar STDOUT.
En el ejemplo que se puede ver a continuación, forzamos un error muy típico en los progrmadores no cerrar
comillas:
print "hola;
31
Can't find string terminator...line 3
Sabemos que con el simbolo > podemos redirigir una salida de pantalla a un archivo. Pero si tecleamos:
El archivo error está vacío. Esto es porque la salida estándar de los errores STDERR es la pantalla. Para que
se grave el error en el archivo hay que direccionar el canal de error, que en Unix es el 2, al archivo. Esto se
hace como sigue:
hola.pl 2>error.txt
open(IN, "data.txt");
open(OUT, ">out.txt");
while($linea = <IN>) {
# manipula los caracteres leidos y puestos en la variable
# $linea. Por ejemplo convertir los caracteres a minúsculas
$linea =~ tr/A-Z/a-z/;
# escritura del resultado
print OUT $linea;
}
close(IN);
close(OUT);
El ejemplo siguiente visualiza en la consola el nombre de cada usuario y su directorio predeterminado. Esta
información se extrae del archivo "/etc/passwd" que contiene la descripción de cada login. Para ello es
necesario saber que cada línea del archivo passwd está compuesta por: el nombre que usa el usuario para
entrar (login), la contraseña encriptada (password), número que identifica al usuario (uid), número que
identifica al grupo al que pertenece el usuario (gid), información sobre el usuario (User_Information),
directorio inicial del usuario (login_directory) y el interprete de comandos usado por dicho usario
(login_shell). Esta información relativa al usuario se estructura en dicho fichero en una línea de la siguiente
manera:
login:password:uid:gid:User_Information:login_directory:login_shell
Por tanto, este ejemplo se realizará de la siguiente manera:
open(PASSWD, "/etc/passwd");
while ($p = <PASSWD>) { # lee una línea del archivo
chop($p); #quitamos el salto de línea
@field = split(/:/, $p);
print " Usuario $field[0] y su directorio es $field[5]";
}
close(PASSWD);
32
A continuación se da de alta a un usuario si clave de paso, esto se realiza escribiendo en el archivo
"/etc/passwd":
open(PASS, ">>/etc/passwd");
print PASS, "$login::$uid:$gid:$information:";
print PASS, "$login_dir:$login_shell\n";
close(PASS);
Si STDIN se encuentra del operador <>, lee una línea cada vez desde ese manejador de archivo. Por ejemplo:
$uno = <STDIN>;
$dos =<STDIN>;
print $uno.$dos;
Al ejecutar este script, teclear unas palabras seguidas de enter y repetir lo mismo una segunda vez. A medida
que escribimos <STDIN> lee lo que tecleamos y al pulsar enter lo asigna a la variable $uno. Lo mismo
ocurre le ocurre a $dos. Pero, si se ejecuta este otro script:
Este script permite hacer un bucle para leer y escribir tantas líneas como queramos. La condición se escribe
entre paréntensis y las líneas que hacen el bucle entre llaves. Para finalizar la entradadesde el teclado pulsar
Control+Z.
Por otro lado, el acceso en lectura a un archivo es dependiente del contexto. En un contexto escalar, Perl lee
un archivo línea por línea y lo asigna al escalar. En un contexto de array o lista, el acceso al contenido del
archivo entraña una lectura completa del archivo. Cada elemento del archivo contiene entonces una línea
completa del archivo leído. Por ejemplo:
$file = "datos.txt";
open(DATA, $file) || die "no se puede abrir el archivo\n";
@lineas = <DATA> # lee todo el archivo.
close(DATA);
Esta propiedad debe utilizarse con precaución, porque la lectura completa de un archivo corre el riesgo de ser
muy costosa en memoria. Por otra parte, el lenguaje Perl utiliza caches para las entradas/salidas y en
consecuencia la lectura completa de un archivo no entraña necesariamente una ganancia en materia de
rendiemiento.
3. Los canales de comunicación (pipes).
La rutina open de Perl puede utilizarse tambiém para ejecutar mandatos del shell, modificar sus entradas y
recuperar sus salidas. Cuando el nombre del archivo lleva como prefijo el carácter |, este nombre se trata
como un mandato. Este mandato se ejecuta y comunica con el script Perl mediante la rutina print. Veamos un
ejemplo:
Por otro lado, cuando el nombre del archivo va seguido del carácter |, el mandato se ejecuta y se puede
acceder a su resultado por medio del operador <>. Por ejemplo:
Por ejemplo:
$data = "data.txt";
if (e- $data) {
# OK, el archivo existe
open ...
}
else {
print "el archivo $data no existe.\n";
}
Si se desea imprimir el % como un carácter dentro de una cadena de control, debe utilizarse %%.
Hay que tener en cuenta que los literales de ristras permiten escribir caracteres especiales con lo que se
denomina un secuencia de escape. La secuencia de escape comienza siempre con "\" y a continuación se
escribe otro carácter que representa el código especial o el número en octal o hexadecimal de su código
ASCII. Las secuencias de escape representan un único carácter en la ristra donde aparecen.
Un ejemplo sencillo:
La función sprintf devuelve una cadena de caracteres formateada por la conveciones normalmente utilizadas
por printf, para ello se recomienda ver las dos tablas anteriores. Para ver mejor el funcionamiento de esta
rutina introducimos el siguiente ejemplo:
35
$lenguaje = "Perl";
$longitud = 10;
$conformato = sprintf("%s", $lenguaje);
print $conformato,"\n"; # Imprime:Perl
$conformato = sprintf(">>%s<<", $lenguaje);
print $conformato,"\n"; # Imprine:>>Perl<<
$conformato = sprintf(">>%s <<", $lenguaje);
print $conformato,"\n"; # Imprime:>>Perl <<
$conformato = sprintf(">>%10s<<", $lenguaje);
print $conformato,"\n"; # Imprime:>> Perl<<
$conformato = sprintf(">>%-10s<<", $lenguaje);
print $conformato,"\n"; # Imprime:>>Perl <<
$conformato = sprintf(">>%-${longitud}s<<", $lenguaje);
print $conformato,"\n"; # Imprime:>>Perl <<
open(DAT,"<datos.txt");
read(DAT, $var, 30);
# $var tiene los primeros 30 caracteres de
# datos.txt
open(DAT,"<datos.txt");
read(DAT, $var, 30);
seek(DAT,-31,1);
read(DAT, $var, 30); # Volvemos a leer lo mismo.
36
open(DAT,"<datos.txt");
read(DAT, $var, 30);
$ptr = tell(DAT); # $ptr = 31;
open(NOM,"<nombres.txt);
while (!(eof(NOM))) {
read(NOM, $nombre, 50);
print $nombre;
}
Variables predefinidas
Las siguientes variables tienen un especial significado para el lenguaje Perl. Estas variables se pueden
clasificar en tres tipos:
1. De fichero.
Estas variables contienen algunos valores perteneciente la manejador de ficheros seleccionado actualmente.
Cada manjador de fichero necesita su propio conjunto de valores. Cuando seleccionamos otro manejador de
fichero, el manejador de fichero anterior mantiene sus valores pero las variables reflejarán ahora los valores
del nuevo. Los variables predefinidas de fichero son las siguientes:
2. Locales.
Estas variables son locales al bloque de código actual. Las variables locales predefinidas son las siguientes:
$1...$9: Contiene la subcadena desde el correspondiente al conjunto de paréntesis en la última cadena
comparada con éxito.
$&: Representa el valor de la última cadena de caracteres comparada con éxito.
$`y $’: Estos dos términos se utilizan conjuntamente para separar cadenas de caracteres comparadas
con éxito. ` es la anterior y ‘ es la siguiente. Ejemplo:
$linea = 'abcdefghi';
$linea =~ /def/;
print "$`:$&:$'\n"; # imprime abc:def:ghi
37
$+: El último éxito de la última búsqueda del último patrón. Es útil cuando no se sabe que patrón de
un conjunto fue el encontrado.
3. Globales.
Estas variables tiene el mismo significado en todo el script, así como en los paquetes que utiliza. Las
variables globales predefinidas son las siguientes:
$_: Contiene el contenido del último registro leído de un fichero. Es el argumento predeterminado
que poseen varias funciones y construcciones en Perl. Por ejemplo:
38
# Lee argumentos de la línea de comando y los lista.
%ENV: Array asociativo que contiene las variables de entorno bajo el que se ejecuta nuestro script
Perl.
$:: El conjunto actual de caracteres tras los que una cadena se rompe para llenar los campos
siguientes (que empiecen con ^) en un formato.
$^D: Los valores actuales de los flags de depuración.
$^F: El máximo descriptor de fichero del sistema, normalmente 2. Los descriptores de fichero del
sistema son pasados a los procesos hijos, mientras que los superiores no. Durante una apertura, los
descriptores de fichero del sistema se guardan, incluso si falla la operación.
$^I: Contiene el valor actual de la extensión del editor. Con undef se desactiva.
$^L: Qué formato utilizar para realizar un salto de línea. Por defecto: \f.
$^P: Flags internos que el depurador borra. Se puede desactivar el depurador borrándolos.
$^T: El tiempo, en segundos, transcurrido desde que el script comenzó a ejecutarse.
$^X: El nombre con el que Perl se ejecutó, argv[0].
$ARGV: Contiene el nombre del fichero actual cuando se lee de <ARGV> .
@INC: El array INC contiene la lista de lugares en donde buscar scripts en Perl para ser evaluados
por el comando "do EXPR" o "require". Contiene inicialmente los argumentos de cualquier línea de
comando -I , seguido de la librería Perl por defecto, probablemente "/usr/local/lib/perl", y un punto
".",para representar el directorio actual.
%INC: El array asociativo INC contiene entradas para cada nombre de fichero que ha sido incluido
vía "do" o "require". La clave es el nombre del fichero especificado y el valor es la localización del
fichero encontrado. El comando "require" usa este array para determinar cuando un fichero ha sido
incluido.
$ENV{expr}: Es un array asociativo que contiene tu entorno actual. El entorno de los procesos hijo
se puede cambiar colocando un valor en este array.
$SIG{expr}: Es otro array asociativo usado para inicializar manejadores de señales para distintas
señales. Este array sólo contiene valores para las señales inicializadas por el script.
39