El comando rename es un estandard Unix que permite renombrar múltiples ficheros. Veamos algunos ejemplos de uso de rename:
rename ’s/\.bak$//’ *.bak rename ’y/A-Z/a-z/’ * rename ’s/\.flip$/.flop/’ # rename *.flip to *.flop rename s/flip/flop/ # rename *flip* to *flop* rename ’s/^s\.(.*)/$1.X/’ rename ’s/$/.orig/ */*.[ch]’ rename ’y/A-Z/a-z/’ rename ’y/A-Z/a-z/ if -B’ # lo mismo pero con binarios rename 's{(\d+)}{"-".(2*$1)}e' node*.html
Veamos el procesado de la línea de comandos:
lhp@nereida:~/Lperl/src/cookbook/ch16$ cat -n /usr/bin/rename 1 #!/usr/bin/perl -w .. ... # comments 32 use strict; 33 34 use Getopt::Long; 35 Getopt::Long::Configure('bundling'); 36 37 my ($verbose, $no_act, $force, $op); 38 39 die "Usage: rename [-v] [-n] [-f] perlexpr [filenames]\n" 40 unless GetOptions( 41 'v|verbose' => \$verbose, 42 'n|no-act' => \$no_act, 43 'f|force' => \$force, 44 ) and $op = shift;
El uso de GetOptions significa que podemos llamar al programa de la forma:
$ rename -n 's/1628/chuchu/' node-1628.html node-1628.html renamed as node-chuchu.html $ ls -l *chuchu* ls: *chuchu*: No existe el fichero o el directorioLa opción
-n
hace que la ejecución sea ''simulada''
$ rename -no 's/1628/chuchu/' node-1628.html Unknown option: o Usage: rename [-v] [-n] [-f] perlexpr [filenames]
La llamada Getopt::Long::Configure('bundling')
hace
que sea posible juntar varias opciones. Por ejemplo, si
a
, v
y x
son opciones válidas, entonces
un agrupamiento como -vax
activa las tres.
Como se ha usado bundling, -no
es sinónimo
de -n
-o
. Si se quieren usar prefijos o nombres completos
se debe usar el formato largo con dos guiones:
$ rename --no-act 's/1628/chuchu/' node-1628.html node-1628.html renamed as node-chuchu.htmlLa presencia de la opción
n
o de --no-act
hace que la variable $no_act
se inicia a verdadero.
La función GetOptions retorna falso si se produjo un error
procesando la línea de comandos. Los argumentos no procesados,
aquellos que no se corresponden a las opciones descritas en la llamada
permancen en @ARGV
.
Véase la documentación del módulo Getopt::Long para los detalles.
Si $no_act
se adopta el modo $verbose
:
46 $verbose++ if $no_act;
Si no se proveen ficheros se leen desde STDIN
:
48 if (!@ARGV) { 49 print "reading filenames from STDIN\n" if $verbose; 50 @ARGV = <STDIN>; 51 chop(@ARGV); 52 }
El programa pasado como argumento es evaluado en la línea
56. Si contiene errores $@
contendrá el mensaje de
error (línea 57).
54 for (@ARGV) { 55 my $was = $_; # viejo nombre del fichero 56 eval $op; # sustitución efectuada 57 die $@ if $@; # alto si la expresión es inválidaSi el nuevo nombre es igual al viejo no se hacen cambios:
58 next if $was eq $_; # ignore quietlyA menos que se especificara
--force
no se renombra el fichero si existe ya uno con ese nombre:
59 if (-e $_ and !$force) # existe fichero con el 60 { # nuevo nombre 61 warn "$was not renamed: $_ already exists\n"; 62 }La evaluación en cortocircuito hace que si se especifico la opción
--no-act
no se ejecute rename
:
63 elsif ($no_act or rename($was, $_)) # Se renombran mediante "rename" 64 { 65 print "$was renamed as $_\n" if $verbose; 66 } 67 else 68 { 69 warn "Can't rename $was $_: $!\n"; 70 } 71 }
Si $no_act
es verdadero nunca se evalúa rename($was, $_)
y se pasa
a ejecutar la línea 65.
Sigue el código completo:
pp2@europa:~$ sed -ne '32,71p' `which rename` | cat -n 1 use strict; 2 3 use Getopt::Long; 4 Getopt::Long::Configure('bundling'); 5 6 my ($verbose, $no_act, $force, $op); 7 8 die "Usage: rename [-v] [-n] [-f] perlexpr [filenames]\n" 9 unless GetOptions( 10 'v|verbose' => \$verbose, 11 'n|no-act' => \$no_act, 12 'f|force' => \$force, 13 ) and $op = shift; 14 15 $verbose++ if $no_act; 16 17 if (!@ARGV) { 18 print "reading filenames from STDIN\n" if $verbose; 19 @ARGV = <STDIN>; 20 chop(@ARGV); 21 } 22 23 for (@ARGV) { 24 my $was = $_; 25 eval $op; 26 die $@ if $@; 27 next if $was eq $_; # ignore quietly 28 if (-e $_ and !$force) 29 { 30 warn "$was not renamed: $_ already exists\n"; 31 } 32 elsif ($no_act or rename $was, $_) 33 { 34 print "$was renamed as $_\n" if $verbose; 35 } 36 else 37 { 38 warn "Can't rename $was $_: $!\n"; 39 } 40 }