domingo, 9 de septiembre de 2007

Renombramiento masivo de archivos

Sería interesante poder hacer un Find and Replace sobre los nombres de los archivos contenidos en un directorio, tan fácilmente como se hace por ejemplo desde KWrite. Para esto, podemos usar el siguiente comando:

for file in *; do mv $file `echo $file | \
           sed 's/TEX_ORIG/TEX_REEMP/g'`; done;



Lo que hace es iterar sobre los nombres de los archivos que matchean * (que podría ser también algo como *.avi o cualquier otra extensión) y ejecutar por cada uno de ellos una llamada a mv, renombrando el archivo de nombre $file (archivo actual de la iteración) por el resultado de hacer un reemplazo sobre el texto que lo compone utilizando sed.

También es posible el uso de expresiones regulares en general para hacer el reemplazo. De esta manera se puede matchear algún trozo de texto particular de $file y utilizarlo para formar el nombre de archivo destino. Por ejemplo:

$ ls
1.pdf 2.pdf 3.pdf 4.pdf 5.pdf 6.pdf 7.pdf 8.pdf 9.pdf

$ for file in *.pdf; do mv $file `echo $file | \
           sed 's/\^([0-9]*\).pdf/archivo-\1.pdf/g'`; done;

$ ls
archivo-1.pdf archivo-3.pdf archivo-5.pdf archivo-7.pdf archivo-9.pdf
archivo-2.pdf archivo-4.pdf archivo-6.pdf archivo-8.pdf



En este caso estamos utilizando grupos, delimitándolos con \( y \). De esta manera los nombres de archivo que consistan en una tira de dígitos (que es almacenada en \1) seguida por '.pdf', van a ser renombrados a 'archivo-' + tira_de_dígitos + '.pdf'.

Nótese que si el texto en $file no matchea la expresión regular, se estaría intentando mover un archivo con igual destino y origen (sed no modifica el texto de entrada), lo que causaría que se despliegue algo como 'mv: `X.pdf' and `X.pdf' are the same file' en pantalla. De todas formas, esto no afecta al renombramiento del resto de los archivos.

No hay comentarios: