• Publicidad

Renombrar archivos según su nombre

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Renombrar archivos según su nombre

Notapor roxana_ » 2010-11-17 20:14 @885

¡Hola!

Mi problema es modificar el nombre de muchos archivos, según el nombre original debo renombrarlos de una manera particular. Tengo un archivo con:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
nombre1 código1
nombre2 código2
nombre3 código3
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Por otro lado en un directorio tengo los archivos a renombrar:
nombre1#nombre2.bezA.txt
nombre1#nombre2.bezB.txt
nombre2#nombre2.bezA.txt
nombre2#nombre3.bezB.txt

A cada archivo quiero agregarle el código que le corresponde según el archivo que describí primero. El nombre que tengo que tomar del archivo a renombrar para saber el código que le corresponde, depende si dice A o B antes de la extensión. Si dice A tomo el primer nombre que aparece (antes del #), si dice B el segundo.

La salida deseada para el ejemplo sería:
código1.nombre1#nombre2.bezA.txt
código2.nombre1#nombre2.bezB.txt
código2.nombre2#nombre2.bezA.txt
código3.nombre2#nombre3.bezB.txt

Espero que se entienda. ¿Es adecuado usar Perl para lo que necesito hacer?
roxana_
Perlero nuevo
Perlero nuevo
 
Mensajes: 14
Registrado: 2010-11-04 15:18 @679

Publicidad

Re: Renombrar archivos según su nombre

Notapor explorer » 2010-11-18 06:02 @293

Perl está perfectamente capacitado para realizar operaciones de administración. De hecho, sigue siendo una de las herramientas más utilizadas para administración.

Aquí tienes la resolución del problema:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5.  
  6. ## Lectura de los códigos
  7. my %codigos;
  8.  
  9. open my $fichero_codigos, '<', 'kk.txt';
  10. while (<$fichero_codigos>) {
  11.     chomp;
  12.     my ($nombre, $codigo) = split;
  13.  
  14.     $codigos{ $nombre } = $codigo;
  15. }
  16. close $fichero_codigos;
  17.  
  18.  
  19. ## Entramos en el directorio con los ficheros a renombrar
  20. chdir 'txt';
  21.  
  22.  
  23. ## Renombrado
  24. for my $fichero (<*.txt>) {
  25.  
  26.     my ($nombre1, $nombre2, $resto, $tipo) = $fichero =~ /^(.+?)#(.+?)[.](.+?)(.)[.]txt$/;
  27.  
  28.     # Clasificación
  29.     my $codigo;
  30.  
  31.     if ($tipo eq 'A') {
  32.         $codigo = $codigos{$nombre1};
  33.     }
  34.  
  35.     if ($tipo eq 'B') {
  36.         $codigo = $codigos{$nombre2};
  37.     }
  38.  
  39.     my $nuevo = "$codigo.$nombre1#$nombre2.$resto$tipo.txt";
  40.  
  41.     print "[$fichero] : [$nombre1, $nombre2, $resto, $tipo] => [$nuevo]\n";
  42.  
  43.     rename $fichero, $nuevo;
  44. }
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

Explicación:
  1. De la línea 9 a la 16 leemos el fichero de códigos, que convertimos en un hash, donde las claves son los nombres, y los valores, los códigos.
  2. En la línea 20 entramos en el directorio donde se encuentran los ficheros a renombrar. Si este programa lo ejecutáramos ya dentro de él, no sería necesaria esta línea.
  3. El bucle que empieza en la 24, recorre todos los ficheros que acaben en .txt.
  4. En la 26, con la ayuda de una expresión regular, partimos el nombre del $fichero en sus distintos componentes. El patrón /^(.+?)#(.+?)[.](.+?)(.)[.]txt$/ quiere decir: "comienza (^) por un conjunto de caracteres (.+?), seguido por '#', seguido por otro conjunto de caracteres (.+?), seguido por un '.', seguido por otro conjunto de caracteres (.+?), seguido por un carácter más, seguido por un '.' y 'txt', y no hay nada más ($)". Cada parte interesante es almacenada en su correspondiente variable.
  5. Del 31 al 37, según el $tipo, obtenemos el $codigo que pondremos delante.
  6. De la 39 a la 43, construimos el nuevo nombre del fichero, informamos al usuario, y renombramos.

Si, por ejemplo, supiéramos que todos los nombres de los ficheros a renombrar, tienen la misma longitud y los nombres y los códigos son también iguales en longitud de caracteres, se podría cambiar la expresión regular por una función unpack() o varias substr() para extraer los distintos valores de cada nombre de fichero.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Renombrar archivos según su nombre

Notapor roxana_ » 2010-11-18 10:53 @495

¡Hola! Gracias por la ayuda. Cometí un error al describir los nombres de los archivos a renombar. Es:
nombre1#nombre2.número.bezB.txt

Supongo que debo cambiar la línea 26
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.   my ($nombre1, $nombre2, $resto, $tipo) = $fichero =~ /^(.+?)#(.+?)[.](.+?)(.)(.+?)[.]txt$/;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¿Es correcto?
roxana_
Perlero nuevo
Perlero nuevo
 
Mensajes: 14
Registrado: 2010-11-04 15:18 @679

Re: Renombrar archivos según su nombre

Notapor explorer » 2010-11-18 11:09 @506

Yo creo que funciona con la línea original...
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Renombrar archivos según su nombre

Notapor roxana_ » 2010-11-18 11:44 @530

Creo que no funciona,cuando lo ejecuto aparece:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
readline() on closed filehandle $fichero_codigos at ./rename_PF.pl line 10 (#1)
    (W closed) The filehandle you're reading from got itself closed sometime
    before now.  Check your control flow.
   
Use of uninitialized value in concatenation (.) or string at ./rename_PF.pl
        line 39 (#2)
    (W uninitialized) An undefined value was used as if it were already
    defined.  It was interpreted as a "" or a 0, but maybe it was a mistake.
    To suppress this warning assign a defined value to your variables.
   
    To help you figure out what was undefined, perl tells you what operation
    you used the undefined value in.  Note, however, that perl optimizes your
    program and the operation displayed in the warning may not necessarily
    appear literally in your program.  For example, "that $foo" is
    usually optimized into "that " . $foo, and the warning will refer to
    the concatenation (.) operator, even though there is no . in your
    program.
[Zot#Zot.1.bezA.txt] : [Zot, Zot, 1.bez, A] => [.Zot#Zot.1.bezA.txt]
[Zot#Zot.1.bezB.txt] : [Zot, Zot, 1.bez, B] => [.Zot#Zot.1.bezB.txt]
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


y no sé adónde van a parar los archivos :S
roxana_
Perlero nuevo
Perlero nuevo
 
Mensajes: 14
Registrado: 2010-11-04 15:18 @679

Re: Renombrar archivos según su nombre

Notapor explorer » 2010-11-18 12:41 @570

El error es porque $codigo, en la línea 39, no tiene ningún valor. Y eso es porque no se ha encontrado ningún valor en %codigos correspondiente a $nombre1 o $nombre2, y como los dos tienen el valor Zot, quiere decir que ese valor no existe en el hash. Y por lo tanto, no existe ese valor en el fichero de códigos.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Renombrar archivos según su nombre

Notapor roxana_ » 2010-11-18 14:32 @647

Bueno gracias, revisaré mis archivos :)
roxana_
Perlero nuevo
Perlero nuevo
 
Mensajes: 14
Registrado: 2010-11-04 15:18 @679


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 29 invitados