web-dev-qa-db-fra.com

Encodage Windows-1252 à UTF-8

J'ai copié certains fichiers d'une machine Windows vers une machine Linux. Ainsi, tous les fichiers Windows encodés (Windows-1252) doivent être convertis au format UTF-8. Les fichiers qui sont déjà dans UTF-8 ne doivent pas être modifiés. Je prévois d'utiliser l'utilitaire recode pour cela. Comment puis-je spécifier que l'utilitaire recode doit uniquement convertir les fichiers codés Windows-1252 et non les fichiers UTF-8?

Exemple d'utilisation de recode:

recode windows-1252.. myfile.txt

Cela convertirait myfile.txt de Windows-1252 en UTF-8. Avant de faire cela, j'aimerais savoir que myfile.txt est en fait codé par Windows-1252 et non par UTF-8. Sinon, je pense que cela corromprait le fichier.

31
Sam

Comment croyez-vous que recode sache qu'un fichier est Windows-1252? En théorie, je pense que le fichier any est un fichier Windows-1252 valide, car il mappe tous les octets possibles à un caractère.

Maintenant, il existe certainement des caractéristiques qui suggéreraient fortement qu’il s’agissait du format UTF-8 - s’il commence par la nomenclature UTF-8, par exemple - mais elles ne seraient pas définitives.

Une option serait de détecter s’il s’agissait en fait d’un fichier UTF-8 complètement valide en premier, je suppose ... encore une fois, ce ne serait que suggestif.

Je ne connais pas bien l'outil de recodage lui-même, mais vous voudrez peut-être savoir s'il est capable de recoder un fichier depuis et vers le codage same - si vous le faites avec un fichier non valide (c'est-à-dire contenant un fichier UTF non valide -8 séquences d’octets) peut convertir les séquences invalides en points d’interrogation ou quelque chose de similaire. À ce stade, vous pouvez détecter qu'un fichier est en UTF-8 valide en le recodant au format UTF-8 et en vérifiant si les entrées et les sorties sont identiques.

Sinon, faites-le par programme plutôt que d'utiliser l'utilitaire de recodage - ce serait assez simple en C #, par exemple.

Juste pour répéter cependant: tout cela est heuristique. Si vous ne connaissez pas vraiment l'encodage d'un fichier, rien ne vous le dira avec une précision de 100%.

37
Jon Skeet

vous pouvez utiliser iconv:

iconv -f WINDOWS-1252 -t UTF-8 filename.txt

62
Gregory Pakosz

Voici une transcription d'une autre réponse que j'ai donnée à une question similaire:

Si vous appliquez utf8_encode () à une chaîne déjà en UTF8, une sortie UTF8 tronquée sera renvoyée.

J'ai créé une fonction qui aborde tous ces problèmes. C'est appelé Encoding :: toUTF8 ().

Vous n'avez pas besoin de savoir quel est l'encodage de vos chaînes. Il peut s'agir de Latin1 (iso 8859-1), Windows-1252 ou UTF8, ou la chaîne peut en contenir plusieurs. Encodage :: toUTF8 () convertira tout en UTF8.

Je l'ai fait parce qu'un service me donnait un flux de données tout mélangé, mélangeant UTF8 et Latin1 dans la même chaîne.

Usage:

$utf8_string = Encoding::toUTF8($utf8_or_latin1_or_mixed_string);

$latin1_string = Encoding::toLatin1($utf8_or_latin1_or_mixed_string);

Télécharger:

https://github.com/neitanod/forceutf8

Mettre à jour:

J'ai inclus une autre fonction, Encoding :: fixUFT8 (), qui corrigera toutes les chaînes UTF8 qui ont l'air déformées. 

Usage:

$utf8_string = Encoding::fixUTF8($garbled_utf8_string);

Exemples:

echo Encoding::fixUTF8("Fédération Camerounaise de Football");
echo Encoding::fixUTF8("Fédération Camerounaise de Football");
echo Encoding::fixUTF8("FÃÂédÃÂération Camerounaise de Football");
echo Encoding::fixUTF8("Fédération Camerounaise de Football");

affichera:

Fédération Camerounaise de Football
Fédération Camerounaise de Football
Fédération Camerounaise de Football
Fédération Camerounaise de Football

Mise à jour: j'ai transformé la fonction (forceUTF8) en une famille de fonctions statiques dans une classe appelée Encodage. La nouvelle fonction est Encoding :: toUTF8 ().

9
Sebastián Grignoli

Il n'y a pas de moyen général de savoir si un fichier est encodé avec un encodage spécifique. N'oubliez pas qu'un codage n'est rien d'autre qu'un "accord" sur la manière dont les bits d'un fichier doivent être mappés sur des caractères.

Si vous ne savez pas quels fichiers sont déjà encodés dans UTF-8 et quels fichiers sont encodés dans Windows-1252, vous devrez inspecter tous les fichiers et trouver vous-même. Dans le pire des cas, cela pourrait signifier que vous deviez ouvrir chacun d'entre eux avec l'un des deux encodages et voir s'ils "semblaient" corrects - c'est-à-dire que tous les caractères sont affichés correctement. Bien sûr, vous pouvez utiliser le support des outils pour le faire, par exemple, si vous savez avec certitude que certains caractères sont contenus dans les fichiers qui ont un mappage différent dans Windows-1252 par rapport à UTF-8, vous pouvez les grep après avoir exécuté les fichiers via "iconv" comme mentionné par Seva Akekseyev.

Si vous saviez que les fichiers ne contiennent en réalité que des caractères codés de manière identique à la fois dans UTF-8 et dans Windows-1252, vous auriez un autre cas heureux. Dans ce cas, bien sûr, vous avez déjà terminé.

8
kleiba

Si vous souhaitez renommer plusieurs fichiers en une seule commande (par exemple, vous voulez convertir tous les fichiers *.txt), voici la commande:

find . -name "*.txt" -exec iconv -f WINDOWS-1252 -t UTF-8 {} -o {}.ren \; -a -exec mv {}.ren {} \;
5
Anthony O.

Utilisez la commande iconv .

Pour vous assurer que le fichier est dans Windows-1252, ouvrez-le dans le Bloc-notes (sous Windows), puis cliquez sur Enregistrer sous. Le Bloc-notes suggère le codage actuel comme codage par défaut. s'il s'agit de Windows-1252 (ou de toute page de code d'un octet, d'ailleurs), la mention "ANSI" sera utilisée.

2
Seva Alekseyev

Vous pouvez modifier le codage d'un fichier avec un éditeur tel que notepad ++. Il suffit d'aller à Encodage et sélectionnez ce que vous voulez.

Je préfère toujours le Windows 1252

1
thanos.a

UTF-8 n'a pas de nomenclature, car elle est à la fois superflue et invalide. UTF-16 peut être utile dans une nomenclature qui peut être permutée en octets, comme dans le cas de Microsoft. UTF-16 si pour une représentation interne dans une mémoire tampon. Utilisez UTF-8 pour l’échange. Par défaut, à la fois UTF-8, tout ce qui est dérivé de US-ASCII et UTF-16 est un ordre d'octets naturel/réseau. Microsoft UTF-16 nécessite une nomenclature car il s'agit d'une permutation d'octets.

Pour convertir Windows-1252 en ISO8859-15, je convertis d'abord ISO8859-1 en US-ASCII pour les codes avec des glyphes similaires. Je convertis ensuite Windows 1252 jusqu'à ISO8859-15, d'autres glyphes non ISO8859-15 en plusieurs caractères US-ASCII.

0

Trouvé cette documentation pour la commande TYPE :

Convertissez un fichier ASCII (Windows1252) en fichier texte Unicode (le fichier UCS-2): 

For /f "tokens=2 delims=:" %%G in ('CHCP') do Set _codepage=%%G    
CHCP 1252 >NUL    
CMD.EXE /D /A /C (SET/P=ÿþ)<NUL > unicode.txt 2>NUL    
CMD.EXE /D /U /C TYPE ascii_file.txt >> unicode.txt    
CHCP %_codepage%    

La technique ci-dessus (basée sur un script de Carlos M.) crée tout d'abord un fichier avec une marque d'ordre d'octet (BOM), puis ajoute le contenu du fichier d'origine. CHCP permet de s’assurer que la session est en cours d’exécution avec la page de codes Windows1252 afin que les caractères 0xFF et 0xFE () soient interprétés correctement.

0
Napfkuchen

Si vous êtes sûr que vos fichiers sont au format UTF-8 ou Windows 1252 (ou Latin1), vous pouvez tirer parti du fait que recodage se terminera par une erreur si vous essayez de convertir un fichier non valide.

Alors que utf8 est valide Win-1252, l'inverse n'est pas vrai: win-1252 N'EST PAS valide UTF-8. Alors:

recode utf8..utf16 <unknown.txt >/dev/null || recode cp1252..utf8 <unknown.txt >utf8-2.txt

Va cracher des erreurs pour tous les fichiers cp1252, puis procéder à la conversion en UTF8.

Je voudrais envelopper cela dans un script bash plus propre, en gardant une sauvegarde de chaque fichier converti.

Avant de convertir les jeux de caractères, vous voudrez peut-être tout d’abord vous assurer que les fins de ligne sont cohérentes dans tous les fichiers. Sinon, recode s'en plaindra à cause de cela et risque de convertir des fichiers qui étaient déjà au format UTF8 mais dont les fins de ligne étaient erronées.

0
mivk