Convertir à la volée l’encodage des fichiers avec Python

convertir encodage python

Convertir à la volée l’encodage des fichiers avec Python

Il y a encore quelques années, j’étais un petit con qui écrivait ses codes en ISO… Cela me suffisait. Mais voilà! Entre temps, j’ai été contaminé par le virus UTF-8. Alors du coup, quand il m’arrive de reprendre de très vieux fichiers, il faut que je les convertisse en UTF-8. Et quand il y a tout un répertoire, autant dire que je n’ai pas du tout envie de m’y coller manuellement.

Conversion de l’encodage d’un fichier: première approche

Je suis tombé un jour sur un code, sans doute trop vieux, qui est à mes yeux assez long… et qui ne fonctionne pas chez moi:

def typecode(dossier,fichier): # détermine l'encodage du fichier
    d = os.path.join(dossier, fichier)
    fich = open(d,'rb')
    contenu=fich.read()
    fich.close()
    codage=chardet.detect(contenu)['encoding']
    return codage

def conversion(dossier,fichier): # conversion en utf-8
    fichiertemp="utf-"+fichier
    conv = "iconv -f " + 'latin1' + " -t utf-8 "+ fichier + " > " + fichiertemp
    os.system(conv)

def suppression(dossier,fichier):
    ## je sais que c'est étrange mais sinon, le changement
    ## de nom fait apparaître des caractères non conformes
    source="utf-"+fichier
    destination=fichier
    temporaire = "temp-"+fichier
    os.rename(source,temporaire)
    retour = source + " renommé en " + destination
    os.remove(fichier)
    os.rename(temporaire,destination)
    print(retour)

def convertir(dossier,fichier): # conversion des fichiers
    chemin = os.path.join(dossier, fichier)
    if os.path.splitext(chemin)[1] in liste_ext:
        code = typecode(dossier,fichier)
        if code =='windows-1251' or code == 'ISO-8859-2' \
        or code == 'ISO-8859-2' or code == 'latin1' \
        or code == 'windows-1255':
            conversion(dossier,fichier)
            retour = fichier + ' converti de ' + code + ' en utf-8'                 
        elif code == 'utf-8' or code == 'UTF-8':
            retour = fichier + ' déjà au format ' + code
        else:
            try:
                retour = fichier + ' au format ' + code
            except:
                retour=None
                pass
        print(retour)
    

curdir='.' # remplacer ici par le chemin

for dossier, sous_dossiers, fichiers in os.walk(curdir):
    if fichiers != []:
        print("Sous dossiers : %s" % sous_dossiers)              
        for fichier in fichiers:
            try:
                convertir(dossier,fichier)
            except:
                continue
        
rep = input("On efface les fichiers non codés en utf-8 et on les renomme ? (O / N) ATTENTION : plus de fichiers ISO ensuite !")
if rep == 'O':
    for dossier, sous_dossiers, fichiers in os.walk(curdir):
        if fichiers !=[]:
            for fichier in fichiers:
                if os.path.exists(fichier) and os.path.exists("utf-"+fichier):
                    suppression(dossier,fichier)
                else:
                    if os.path.exists(fichier):
                        print(fichier, "intact")

Ce code m’a paru beaucoup trop long pour le peu de chose qu’il doit faire. De plus, la commande iconv ne semblait pas trop fonctionner… J’ai donc écrit un petit programme tout bête.

Mon programme Python pour convertir l’encodage d’un fichier

# Auteur: Stéphane Pasquet
# Site : https://mathweb.fr
# Date : 2021/05/27

from os import walk, getcwd, mkdir
from os.path import isdir
from chardet import detect

rep_courant = getcwd()
directory_utf = rep_courant + '\\utf8'

if not isdir(directory_utf):
    mkdir(directory_utf)

for dossier, sous_dossiers, fichiers in walk(rep_courant):
    for fichier in fichiers:
        if fichier[-3:] == 'tex':
            d = rep_courant + '\\' + fichier
            fich = open(d,'rb')
            txt = fich.read()
            fich.close()
            codage = detect(txt)['encoding']
            if codage != 'utf-8':
                Fichier = open(d , 'r')
                contenu = ""
                for ligne in Fichier.read():
                    contenu += str(ligne)

                Fichier2 = open( directory_utf + '\\' + fichier , 'w' , encoding = 'utf-8')
                Fichier2.write( contenu )
                Fichier2.close()

L’idée ici est de sauvegarder ce script Python dans le répertoire des fichiers à convertir, puis de parcourir ce répertoire: si on rencontre un fichier “.tex” (l’extension peut bien sûr être choisie à votre convenance) et si l’encodage n’est pas UTF-8, alors on l’ouvre en mode binaire et on réécrit son contenu dans un autre fichier qui sera sauvegardé en UTF-8 dans un répertoire (ici, nommé “utf8”).

Stéphane Pasquet
Stéphane Pasquet

Laissez votre message