tr y split

El operador de traducción permite la conversión de unos caracteres por otros. Tiene la sintáxis:

tr/SEARCHLIST/REPLACEMENTLIST/cds
y/SEARCHLIST/REPLACEMENTLIST/cds

El operador permite el reemplazo carácter a carácter, por ejemplo:

$ perl -de 0
  DB<1> $a = 'fiboncacci'
  DB<2> $a =~ tr/aeiou/AEIOU/
  DB<3> print $a
fIbOncAccI
  DB<4> $a =~ y/fbnc/FBNC/
  DB<5> print $a
FIBONCACCI
El operador devuelve el número de carácteres reeemplazados o suprimidos.
$cnt = $sky =~ tr/*/*/; # count the stars in $sky

Si se especifica el modificador /d, cualquier carácter en SEARCHLIST que no figure en REPLACEMENTLIST es eliminado.

  DB<6> print $a
FIBONCACCI
  DB<7> $a =~ y/OA//d
  DB<8> print $a
FIBNCCCI

Si se especifica el modificador /s, las secuencias de carácteres consecutivos que serían traducidas al mismo carácter son comprimidas a una sola:

  DB<1> $b = 'aaghhh!'
  DB<2> $b =~ tr/ah//s
  DB<3> p $b
agh!

Observa que si la cadena REPLACEMENTLIST es vacía, no se introduce ninguna modificación.

Si se especifica el modificador /c, se complementa SEARCHLIST; esto es, se buscan los caracteres que no están en SEARCHLIST.

tr/a-zA-Z/ /cs; # change non-alphas to single space

Cuando se dan múltiples traducciones para un mismo carácter, solo la primera es utilizada:

tr/AAA/XYZ/

traducirá A por X.

El siguiente script busca una expresión regular en el fichero de passwords e imprime los login de los usuarios que casan con dicha cadena. Para evitar posibles confusiones con las vocales acentuadas se usa el operador tr.

   1 #!/usr/bin/perl -w
   2 $search = shift(@ARGV) or die("you must provide a regexpr\n");
   3 $search =~ y/ÁÉÍÓÚáéíóú/AEIOUaeiou/;
   4 open(FILE,"/etc/passwd");
   5 while ($line = <FILE>) {
   6   $line =~ y/ÁÉÍÓÚáéíóú/AEIOUaeiou/;
   7   if ($line =~ /$search/io) {
   8     @fields = split(":",$line);
   9     $login = $fields[0];
  10     if ($line !~ /^#/) {
  11       print "$login\n";
  12     }
  13     else {
  14       print "#$login\n";
  15     }
  16   }
  17 }
  18

Ejecución (suponemos que el nombre del fichero anterior es split.pl):

> split.pl Rodriguez
##direccion
call
casiano
alu5
alu6
##doctorado
paco
falmeida
##ihiu07

Para familiarizarte con este operador, codifica y prueba el siguiente código:

   1 #!/usr/bin/perl -w
   2 $searchlist = shift @ARGV;
   3 $replacelist = shift @ARGV;
   4 $option = "";
   5 $option = shift @ARGV if @ARGV;
   6 
   7 while (<>) {
   8   $num = eval "tr/$searchlist/$replacelist/$option";
   9   die $@ if $@;
  10   print "$num: $_";
  11 }

Perl construye la tabla de traducción en ``tiempo de compilación''. Por ello ni SEARCHLIST ni REPLACEMENTLIST son susceptibles de ser interpolados. Esto significa que si queremos usar variables tenemos que recurrir a la función eval.

La expresión pasada como parámetro a eval en la línea 8 es analizada y ejecutada como si se tratara de un pequeño programa Perl. Cualquier asignación a variables permanece después del eval, asi como cualquier definición de subrutina. El código dentro de eval se trata como si fuera un bloque, de manera que cualesquiera variables locales (declaradas con my) desaparecen al final del bloque.

La variable $@ contiene el mensaje de error asociado con la última ejecución del comando eval. Si es nula es que el último comando se ejecuto correctamente. Aqui tienes un ejemplo de llamada:

> tr.pl 'a-z' 'A-Z' s
jose hernandez
13: JOSE HERNANDEZ
joosee hernnandez
16: JOSE HERNANDEZ

Casiano Rodríguez León
2013-04-23