1:#!/bin/bash
   2:#
   3:# Conversion de toute une arborescence d'un encodage dans un autre.
   4:# Exemple d'utilisation : 
   5:#  mise a jour de sa distribution Linux de iso-8859-1 vers UTF-8
   6:#
   7:# Necessite : convmv et iconv
   8:#
   9:# Utilisation :
  10:# $ ./convertEnc.sh Documents/Divers 
  11:#
  12:# IMPORTANT : faites une copie de vos donnees et travaillez sur cette copie !!
  13:# (Je ne peux etre tenu responsable si vous corrompez vos donnees, soyez prudents)
  14:#
  15:# Ce script ne demande qu'a etre ameliore...
  16:#
  17:## Protection contre les espaces (JacquesF -> guillemets autour des variables ou cela n'etait pas fait)
  18:#
  19:# Sebastien de Boissieu (c) 2006
  20:# $Id: convertEnc.sh,v 1.8.2.1 2007/03/17 22:39:29 sebastien Exp $
  21:# Licence : GPL 2
  22:
  23:FROM="iso-8859-1"
  24:TO="UTF-8"
  25:
  26:echo "Conversion de $FROM en $TO"
  27:
  28:# Procedure pour renommer un fichier si nom deja existant
  29:renomme()
  30:{
  31:nbe=0
  32:num="_$nbe"
  33:nouvnom="$1"
  34:while [ -e "$nouvnom" ];
  35:do
  36:    let nbe=nbe+1
  37:    num="_$nbe"
  38:    nouvnom="$1$num"
  39:done
  40:export nouvnom
  41:}
  42:
  43:# Conversion recursive des noms de fichiers et repertoires
  44:convert_names()
  45:{
  46:echo "Conversion des NOMS de fichiers et repertoires"
  47:#convmv -r -f $FROM -t $TO --qfrom --qto --notest "$1"
  48:convmv -r -f $FROM -t $TO --notest "$1"
  49:echo ""
  50:}
  51:
  52:# Routine de conversion du contenu d'un fichier
  53:do_convert()
  54:{
  55:fic="$1"
  56:echo "  Fichier $fic"
  57:# Lecture du type mime
  58:encForm=`file -bi "$fic" | awk -F "charset=" '{ print $2 }'`
  59:if [ !  "$encForm" = "" ]; then
  60:    # le fichier possede un charset
  61:    echo "  -> $encForm"
  62:    if [ ! "$encForm" = "$TO" ]; then
  63:        # ce charset est different de celui vise
  64:        # nom du fichier converti temporaire
  65:        renomme "$fic"_"$TO"
  66:        nouv_fic="$nouvnom"
  67:        # la conversion
  68:        iconv -f "$encForm" -t $TO "$fic" -o "$nouv_fic"
  69:        # reussite ou echec de la commande cruciale ?
  70:        status=$?
  71:        if [ $status == 0 ]; then
  72:            # Pour conserver la/les date(s) :
  73:            touch -r "$fic" "$nouv_fic"
  74:            # Pour conserver le proprietaire
  75:            chown --reference "$fic" "$nouv_fic"
  76:            # pour conserver les droits :
  77:            chmod --reference "$fic" "$nouv_fic"
  78:            # on ecrase l'ancien fichier par le nouveau
  79:            if [ -w "$fic" ] ; then
  80:                ### JacquesF
  81:                ### Sur mes tests, si le fichier n'est pas accessible en ecriture
  82:                ### un mv -f sur le fichier remplace pourtant celui-ci (droits d'ecriture dans le repertoire)
  83:                mv -f "$nouv_fic" "$fic"
  84:            else
  85:                echo "Le fichier $fic n'est pas accessible en ecriture"
  86:                echo "Le fichier converti se nomme $nouv_fic"
  87:            fi
  88:        else
  89:            echo "   -> Echec: $nouv_fic corrompu ?"
  90:            echo "             $fic conserve."
  91:        fi
  92:    fi
  93:fi
  94:
  95:}
  96:
  97:# Conversion recursive du contenu des fichiers texte
  98:convert_content()
  99:{
 100:#echo "Conversion du contenu des fichiers"
 101:if [ -d "$1" ]; then
 102:    # c'est un repertoire
 103:    if [ -x "$1" ]; then
 104:        # On peut entrer dans le repertoire
 105:        echo "Entree dans : $1"
 106:        ### Protection si le repertoire contient un espace 
 107:        chemin_orig="`pwd`"
 108:        cd -- "$1"
 109:        
 110:        # liste complete (avec fichiers caches)
 111:        # Attention : si liste trop longue ca peut planter 
 112:        # passer par xargs --> man xargs
 113:         for fic in `ls * .* | xargs` ; do 
 114:           if [ $fic != "." -a $fic != ".." ]; then
 115:                base_fic=$(basename -- "$fic")
 116:                #echo "$fic -> $base_fic"
 117:                echo " Analyse de : $base_fic"
 118:                # recursivite
 119:                if [ -d "$base_fic" ]; then
 120:                # Si repertoire, on execute la procedure dessus
 121:                convert_content "$base_fic"
 122:                else
 123:                # sinon on fait la conversion
 124:                do_convert "$base_fic"
 125:                fi
 126:            fi
 127:        done
 128:        echo "Sortie de : $1"
 129:        cd "$chemin_orig"
 130:    else
 131:        echo "Entree INTERDITE dans : $1"
 132:    fi
 133:else
 134:    # On fait la conversion sur le fichier
 135:    do_convert "$1"
 136:fi
 137:
 138:}
 139:#=======================================
 140:
 141:# Debut execution
 142:if [ $# -gt 0 ]; then
 143:    ### Alerte avant lancement du script
 144:    clear
 145:    echo -e "\n\nATTENTION : ne travaillez jamais sur les donnees d'origine !"
 146:    echo -e "\nEtes-vous certain de vouloir modifier ces fichiers ?"
 147:    echo -e "\tAppuyez sur Ctrl-C pour annuler ou sur Return pour continuer \c"
 148:    read Tempo
 149:    echo
 150:    ### Fin de l'alerte 
 151:    # pour l'instant on ne considere que le 1er argument
 152:    echo "Sur: $1"
 153:    echo ""
 154:    ###   On n'est pas a l'abri d'un repertoire avec des espaces dans le nom 
 155:    convert_names "$1"
 156:    echo "============="
 157:    # Remarque : si $1 est un repertoire dont le nom a ete converti
 158:    #  le contenu de $1 est obsolete.
 159:    #  on le converti :
 160:    nom=$(echo "$1" | iconv -f $FROM -t $TO)
 161:    convert_content "$nom"
 162:    
 163:    echo "Fini"
 164:else
 165:    echo "Utilisation :"
 166:    echo "$0 chemin/repertoire"
 167:    ### Alerte par precaution
 168:    echo "Ne travaillez jamais sur les donnees d'origine mais seulement sur une copie de celles-ci" 
 169:fi