mercoledì 2 febbraio 2011

Rinominare molti file con Linux

Se vi trovate nella necessità di dover rinominare molti file (intendo anche migliaia di file o più) vi suggerisco di usare un find e di invocare una shell sulla lista dei file ottenuti. Da notare che se invece del find usate il classico ls * si rischia di incorrere nell’errore Bash Tips: Arg list too long. Nella shell invocata dal find usiamo delle variabili in cui memorizziamo il nome del file attuale e il nome che dovrà avere dopo la rinomina. In linux è presente il comando rename che permette di rinominare molti file ma il metodo indicato qui è applicabile a qualunque linux o unix generico (tipo Solaris e AIX ). Vediamo un esempio in cui i file vengono rinominati e  spostati in un percorso diverso (ho messo anche degli echo per visualizzare correttamente il nome del file che dovrà avere dopo la rinomina). Da notare il il carattere di escape per il singolo apice del comando sed. Inoltre prima di eseguire il comando così come riportato sotto, suggerisco di usare cp o di mettere il comando mv dentro a un echo per vedere se il tutto funziona correttamente.

$ find /path/old/backup* -name '*.GZ.bck' -type f -exec sh -c ' \
FILE={}; \

NOBCK=$(echo {} | sed '\'s/.GZ.bck/.GZ/g\''); \

NEWFILE=$(basename $NOBCK); \
echo "FILE: $FILE"; \
echo "NEWFILE: $NEWFILE"; \
ls -l $FILE; \
mv $FILE /path/new/$NEWFILE' \;

Su una distribuzione di tipo Redhat o Fedora invece è presente il comando rename scritto in C che ci semplifica molto il lavoro (ad esempio è comodo per rinominare tutte le immagini delle foto scaricate da una fotocamera).

$ rename .GZ.bck .GZ *.GZ.bck
$ rename .JPG .jpg *.JPG

Sulle distribuzioni Debian-like (tipo Ubuntu) il comando rename in realtà è uno script perl e l’uso di espressioni regolari lo rende più personalizzabile e quindi più potente.

$ rename 's/\.JPG/.jpg/' *.JPG