Pulitura nomi file

Printer-friendly versionPrinter-friendly version
Terminal-01

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. :)

Who Am I?

~redShadow~ A.K.A. Samuele Santi is an Italian Open Source developer, currently working as a freelance developer, mainly in the web applications sector. Favourite programming languages: PHP and, of course, Python!

aircrack (1) cryptography (1) algorythms (1) documentation (2) backup (3) C++ (2) citroen (1) address book (2) code (3) debug (1) contact manager (1) cocktails (1) doku (1) aoe (1) curl (1) blogroll (7) audio (1) circuits (1) arduino (1) alcool (1) dmcrypt (1) caos (1) apt (1) bash (11) como lake rovers (1) Drupal (21) debian (1) cars (1) development (11) camera mia (1) database (3) archive (1) Drupal Forms (1) awstats (3) e-mail (2) 2v (1) cartoons (1) blender (3) apache (1) 3d (3)