Quante volte capita di avere a che fare con file di varia provenienza a cui l'autore si è sbizzarrito a dare nomi assurdi contenenti, oltre a spazi, perfino caratteri in utf-8 ecc..?
Questo script serve per cercare di rimettere un po' a posto le cose, sostituendo spazi con underscore, lettere accentate con lettere "normali", ecc..
Al momento, funziona solo sui file presenti nella cartella corrente (non permette di scendere nelle subdirectory), ma sto lavorando su una prossima versione che sarà invece in grado di farlo (non è semplice come sembra.. soprattutto considerando symlink, ecc.. ecc..)
Scarica il codice qui: clean-filenames.sh
Il primo passaggio elimina tutti i caratteri speciali cercando di sostituirli con un carattere simile in ASCII-128
1 2 3 4 5 6 7 8 9 |
function allowedchars(){ UC_ST="ÀÁÂÃÄÅĂĄÇĆČĎĐàáâãäåăąçćčďđÈÉÊËĘĚĞÌÍÎÏİĹĽŁèéêëęěğìíîïıĺľłÑŃŇÒÓÔÕÖØŐŔŘŚŞŠñńňòóôõöøőŕřśşšŢŤÙÚÛŲÜŮŰÝŹŻŽţťùúûųüůűýÿźżž" UC_RP="AAAAAAAACCCDDaaaaaaaacccddEEEEEEGIIIIILLLeeeeeegiiiiilllNNNOOOOOOORRSSSnnnooooooorrssTTUUUUUUUUYZZZttuuuuuuuyyzzz" sed "y/àèìòùÀÈÌÒÙ/aeiouAEIOU/" | # Replace accented sed "y/$UC_ST/$UC_RP/" | # Replace UTF-8 biletters | sed "s/[^ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\\._0-9\\-]\\+/_/g" # replace strange chars } |
Differente è la sostituzione dei caratteri bilettera, per cui serve una funzione apposta:
1 2 3 4 5 6 7 |
function biletters(){ sed "s/Æ/AE/" | sed "s/Œ/CE/" | sed "s/æ/ae/" | sed "s/œ/ce/" | sed "s/ß/ss/" } |
Poi, il secondo passaggio rimuove i punti duplicati all'interno del nome del file. In futuro, eliminerà anche i punti all'interno del nome del file che non delimitano l'estensione (devo pensare un buon algoritmo per capire quale sia realmente l'estensione del file però, dato che esistono file con estensioni doppie, tipo tar.gz..)
1 2 3 4 5 |
function nodoubledots(){ # no double dot # no trailing dot sed "s/[\\.]\{2,\}/./g" | sed "s/\\.*\$//" #cat } |
Infine, il ciclo principale rinomina i file usando una pipe di funzioni per pulire il nome..
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# # Main script loop.. # if [ "$1" == "" ]; then echo "Usage: $0 <files...>" echo "Clean filenames of specified files/directories" else for OLDNAME in "$@"; do echo "$OLDNAME" | grep -v / &>/dev/null || die_subdir echo -en " * \e[1;33m\"$OLDNAME\"\e[0m ... " NEWNAME="` echo "$OLDNAME" | allowedchars | nodoubledots | lowerext `" if [ "$NEWNAME" != "$OLDNAME" ]; then echo -e "New name: \e[1;31m\"$NEWNAME\"\e[0m" if [ ! -e "$NEWNAME" ]; then mv "$OLDNAME" "$NEWNAME" else echo -e " >> \e[1;31mATTENTION!\e[0m A file with the same name already exists (not overwriting)" fi else echo -e "\e[1;32mFilename is OK\e[0m" fi done fi |
Probabilmente, la prossima versione sarà scritta in Python, e prevederà anche molte più opzioni, sfruttando le potenzialità di quel linguaggio.. :)
Forse la cosa migliore per lavorare con le regexp potrebbe essere il Perl (??), ma è un linguaggio che al momento non conosco a sufficienza, eppoi sto cercando di migliorare le mie conoscenze di Python, indipercui: la prossima versione la scrivo in Python. punto. :)