• Publicidad

Problema con renombrar archivos en un directorio

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

Problema con renombrar archivos en un directorio

Notapor pablgonz » 2013-12-04 12:25 @559

Hola a todos, estoy tratando de renombrar algunos ficheros que tengo dentro un directorio, los ficheros son de la siguiente forma:
test-fig-0.pdf,test-fig-1.pdf,test-fig-2.pdf,test-fig-3.pdf,test-fig-4.pdf
y deseo dejarlos así:
test-fig-1.pdf,test-fig-2.pdf,test-fig-3.pdf,test-fig-4.pdf,test-fig-5.pdf

Estoy intentando usar este script:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $dir_consulta = "$tempDir/$imageDir";
  2. my $fichero = '';
  3. my $resultado = '';
  4. my $renNo = 1;
  5. if(opendir(DIRECTORIO,$dir_consulta))
  6. {
  7.   #Leemos el listado de fichero que lo componen
  8.   foreach (readdir DIRECTORIO)
  9.   {
  10.     $fichero = $_;
  11.     #Seleccionamos los ficheros
  12.     if ($fichero =~ /$name-fig-\d+\.pdf/)
  13.     { # quitamos desde la derecha 5 caracteres 0;.;p;d;f, escapando el punto
  14.       my $nuevo_nombre = substr($fichero,0,-5) . "$renNo\.pdf";
  15.       $resultado = rename("$dir_consulta/$fichero","$dir_consulta/$nuevo_nombre");
  16.       print "Renombrando $fichero a $nuevo_nombre: $resultado : $!\n";
  17.       $renNo = $renNo+1;
  18.     }
  19.   }
  20.   print "FIN\n";
  21. }
  22. else
  23. {
  24.   print "no se abre ".$dir_consulta;
  25. }
  26. closedir DIRECTORIO;
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

pero, no me funciona... es más: no renombra en el orden que deseo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
  1. Renombrando test-fig-1.pdf a test-fig-1.pdf: 1 : Función ioctl no apropiada para el dispositivo
  2. Renombrando test-fig-0.pdf a test-fig-2.pdf: 1 : Función ioctl no apropiada para el dispositivo
  3. Renombrando test-fig-2.pdf a test-fig-3.pdf: 1 : Función ioctl no apropiada para el dispositivo
  4.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
¿Cómo ordeno los archivos del directorio para hacer el cambio en la numeración?
Saludos
Pablo
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)

Publicidad

Re: Problema con renombrar archivos en un directorio

Notapor danimera » 2013-12-04 15:03 @669

Al parecer, entiendo que lo que quieres es sumar una unida al nombre de los ficheros... Pues yo lo haría de la siguiente forma:

Extraería el número con una expresión regular y le restaría una unidad y obviamente los copiaría a otro directorio no al mismo, dentro de tu ciclo foreach haría algo como:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $fichero =~ /(\d+)/;
  2. $numero_nuevo = $1 + 1;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

con este nuevo número, ya no importa el orden, o reemplazo el número en el nombre y copio a otro directorio, o como quieras, creo que lo importantes es sumar la unidad.
100% Telch - Perl Web Programming
Cali PerlMongers: http://cali.pm.org
Avatar de Usuario
danimera
Perlero frecuente
Perlero frecuente
 
Mensajes: 871
Registrado: 2005-06-23 19:02 @834
Ubicación: Colombia

Re: Problema con renombrar archivos en un directorio

Notapor explorer » 2013-12-04 15:04 @670

El truco está en renombrar desde el último archivo al primero. Pero, entonces, primero hay que averiguar cuál es el último, y luego hacer el renombrado. Ejemplo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use feature 'say';
  3.  
  4. my $i = 0;
  5.  
  6. $i++ while -f "test-fig-$i.pdf";                                # averiguar cuál es el último archivo
  7.  
  8. $i--;                                                           # índice del último
  9.  
  10. for my $i (reverse 0 .. $i ) {                                  # hacemos un bucle al revés
  11.  
  12.     my $siguiente = $i + 1;                                     # apuntamos al siguiente
  13.  
  14.     say "renombrando test-fig-$i.pdf a test-fig-$siguiente.pdf";
  15. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
sale:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
renombrando test-fig-4.pdf a test-fig-5.pdf
renombrando test-fig-3.pdf a test-fig-4.pdf
renombrando test-fig-2.pdf a test-fig-3.pdf
renombrando test-fig-1.pdf a test-fig-2.pdf
renombrando test-fig-0.pdf a test-fig-1.pdf
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
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: Problema con renombrar archivos en un directorio

Notapor pablgonz » 2013-12-04 16:21 @723

Genial, renombrar de forma inversa, no se me hubiese ocurrido jamás, estaba intentando con int($2)+1, pero, solo fueron palos de ciego, al final lo deje así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $i = 0;
  2.  
  3. $i++ while -f "$tempDir/$imageDir/$name-fig-$i.pdf";            # averiguar cuál es el último archivo
  4.  
  5. $i--;                                                           # índice del último
  6.  
  7. for my $i (reverse 0 .. $i ) {                                  # hacemos un bucle al revés
  8.  
  9.     my $siguiente = $i + 1;                                     # apuntamos al siguiente
  10.  
  11.     rename("$tempDir/$imageDir/$name-fig-$i.pdf","$tempDir/$imageDir/$name-fig-$siguiente.pdf");
  12.  
  13. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Noté que esta vez, no está $i entre {...}, el otro día me percaté (en otra solución respecto a borrar un archivo) que usabas {$i} para hacerlo más restrictivo (supongo). ¡Aaah!, ¿y si los ficheros de entrada son de la misma forma, pero .jpg o .png? ¿repito la rutina? ¿O puedo generalizarla?

Saludos.

Edito: Si la carpeta images/ ya contiene archivos test-fig-1.pdf, es decir, corro el script dos veces, éste creará copias y copias siguiendo el correlativo 1, 2, 3, ..., n.
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)

Re: Problema con renombrar archivos en un directorio

Notapor pablgonz » 2013-12-05 08:01 @375

Me respondo solo...no se si es la mejor forma, pero, me funciona, primero elimino todos los pdf del directorio (si es que existen) y luego creo los pdf y los vuelvo a enumerar, de esta manera, si corro el script más de una vez, no me creara archivos extra, quedo así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $dir = "$tempDir/$imageDir" ;
  2.  
  3. # Abro y leo el directorio donde están las imágenes
  4.  
  5. opendir (DIR, "$dir/");
  6. my @FILES = grep(/.pdf/,readdir(DIR));
  7. closedir (DIR);
  8.  
  9. # Elimino los PDF si es que existen
  10.  
  11. foreach my $FILES (@FILES) {
  12.    if (-e "$dir/$FILES") {
  13.       unlink("$dir/$FILES");
  14.    }
  15. }
  16. # Los creo nuevamente (útil, estoy modificando el archivo de entrada)
  17. system("convert -density $DPI $tempDir/$name-fig.pdf $imageDir/$name-fig-%d.pdf");
  18.  
  19. # Los enumero de nuevo
  20.  
  21. my $i = 0;
  22.  
  23. $i++ while -f "$tempDir/$imageDir/$name-fig-$i.pdf";            # averiguar cuál es el último archivo
  24.  
  25. $i--;                                                           # índice del último
  26.  
  27. for my $i (reverse 0 .. $i ) {                                  # hacemos un bucle al revés
  28.  
  29.     my $siguiente = $i + 1;                                     # apuntamos al siguiente
  30.  
  31. rename("$tempDir/$imageDir/$name-fig-$i.pdf","$tempDir/$imageDir/$name-fig-$siguiente.pdf");
  32.  
  33.                                 }
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Creo que greep está de sobra y ¿lo puedo hacer más restrictivo al momento de eliminar los pdf del directorio? así como esta elimina TODOS los pdf y solo deseo que elimine $name-fig-*.pdf.
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)

Re: Problema con renombrar archivos en un directorio

Notapor explorer » 2013-12-05 08:41 @403

Volver a crear los documentos es muy ineficiente. Para evitar que te los renumere dos veces, lo que puedes hacer es comprobar primero si existe el archivo con índice 0. Quedaría así (no probado):

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $dir = "$tempDir/$imageDir";
  2.  
  3. # Miro a ver si los archivos han sido creados
  4. my @FILES = <$dir/*.pdf>;
  5.  
  6. if (not @FILES) {                                                   # si no hay archivos...
  7.     # Los creo nuevamente (útil, estoy modificando el archivo de entrada)
  8.     system("convert -density $DPI $tempDir/$name-fig.pdf $imageDir/$name-fig-%d.pdf");
  9. }
  10.  
  11. # Los enumero de nuevo
  12. my $i = 0;
  13.  
  14. while (1) {                                                     # mientras no encontremos el último
  15.     last if not -f "$tempDir/$imageDir/$name-fig-$i.pdf";       # salimos si no existe ese archivo
  16.  
  17.     $i++;                                                       # pasamos al siguiente
  18. }
  19.  
  20. for my $i (reverse 0 .. $i - 1 ) {                              # hacemos un bucle al revés
  21.     my $siguiente = $i + 1;                                     # apuntamos al siguiente
  22.  
  23.     rename("$tempDir/$imageDir/$name-fig-$i.pdf","$tempDir/$imageDir/$name-fig-$siguiente.pdf");
  24. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

El código contempla el caso de que no exista el archivo con índice 0. Es decir: si no existe ese archivo, con el last salimos inmediatamente del bucle while(), y no se ejecuta ninguna vuelta en el bucle for(), por lo que no realiza ningún renombrado.
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: Problema con renombrar archivos en un directorio

Notapor pablgonz » 2013-12-05 09:10 @423

explorer escribiste:Volver a crear los documentos es muy ineficiente.
Gracias por la respuesta, y totalmente de acuerdo, en la mayor parte de los casos, pero en este no. Me explico: si modifico algo en el fichero de entrada (es un fichero latex) como un color, por ejemplo, cuando vuelva a correr el script, éste debe volver a generar las imágenes (pdf). Con tu solución, encontrará los ficheros ya enumerados y saldrá, es decir, quedará con los pdf sin las modificaciones.

Por eso la idea de eliminarlos y volver a crearlos es correcta, solo debo hacerla más restrictiva, en algunas ocasiones en directorio donde están las imágenes ya existen otros pdf que no tienen que ver con los generados por script, entonces, necesito una especie de ¿comodín? para eliminar solo <$name-fig-*.pdf>.

Saludos
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)

Re: Problema con renombrar archivos en un directorio

Notapor explorer » 2013-12-05 11:39 @527

Bueno, pues solo tienes que modificar el programa para que compruebe si hay una entrada nueva. Si es así, elimina los archivos anteriores (unlink glob "$name-fig-*.pdf") y ya puedes pasar a la parte de volver a generarlos.

En caso de que la entrada no sea nueva, pues no haces nada.
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: Problema con renombrar archivos en un directorio

Notapor pablgonz » 2013-12-05 11:47 @532

Un millón de gracias, justo estaba leyendo lo de glob lo cambié a esto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. foreach my $FILES (@FILES) {
  2.    if (-e "$dir/$FILES") {
  3.      unlink glob "$dir/$name-fig-*.pdf"
  4.    }
  5. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
aún sigo pensando que me sobran cosas en el código, ¿es necesario greep?
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)

Re: Problema con renombrar archivos en un directorio

Notapor explorer » 2013-12-05 14:09 @631

Si usas glob("*.pdf"), no necesitas grep().

¿Seguro que el bucle que has puesto está bien?

@FILES contiene el listado de todos los archivos.
Inicias un bucle, y le das a $FILES el nombre del primer archivo.
Compruebas si existe ese archivo.
Si existe, entonces mandas borrar todos los archivos (nótese la presencia del comodín '*').

Entonces...
1) No necesitas comprobar si existe el archivo: existe (siempre), porque lo has leído con <*.pdf> o con readdir.
2) Si mandas borrar todos los archivos, no necesitas recorrer el resto de archivos en el bucle for

Mejor así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. if (@FILES) {      # si hay algún archivo .pdf,
  2.     unlink @FILES; # les borro
  3. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
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

Siguiente

Volver a Básico

¿Quién está conectado?

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