Comment puis-je tester l'encodage d'un fichier texte… Est-il valide et en quoi consiste-t-il?

46

J'ai plusieurs .htmfichiers qui s'ouvrent dans Gedit sans aucun avertissement / erreur, mais lorsque j'ouvre ces mêmes fichiers Jedit, cela m'avertit d'un encodage UTF-8 invalide ...

La balise méta HTML indique "charset = ISO-8859-1". Jedit autorise une liste des codages de secours et une liste des auto-détecteurs de codage (actuellement "BOM XML-PI"), ainsi mon problème immédiat a été résolu. Mais cela m'a fait penser à: Et si les métadonnées n'étaient pas là?

Lorsque les informations de codage ne sont tout simplement pas disponibles, existe-t-il un programme CLI qui permet de "deviner au mieux" les codages pouvant s'appliquer?

Et, bien que ce soit un problème légèrement différent; Existe-t-il un programme CLI qui teste la validité d'un encodage connu ?

Peter.O
la source
Semblable à "Comment détecter automatiquement l'encodage de fichier texte?" superuser.com/questions/301552/…
buzz3791 Le
Voir aussi stackoverflow.com/q/805418/821436 :-)
Réintégrer Monica - M. Schröder le

Réponses:

60

La filecommande fait des "suppositions" sur l'encodage. Utilisez le -iparamètre pour forcer l’ fileimpression d’informations sur le codage.

Manifestation:

$ file -i *
umlaut-iso88591.txt: text/plain; charset=iso-8859-1
umlaut-utf16.txt:    text/plain; charset=utf-16le
umlaut-utf8.txt:     text/plain; charset=utf-8

Voici comment j'ai créé les fichiers:

$ echo ä > umlaut-utf8.txt 

De nos jours, tout est utf-8. Mais convaincez-vous:

$ hexdump -C umlaut-utf8.txt 
00000000  c3 a4 0a                                          |...|
00000003

Comparez avec https://en.wikipedia.org/wiki/Ä#Computer_encoding

Convertir les autres encodages:

$ iconv -f utf8 -t iso88591 umlaut-utf8.txt > umlaut-iso88591.txt 
$ iconv -f utf8 -t utf16 umlaut-utf8.txt > umlaut-utf16.txt 

Vérifiez le vidage hexadécimal:

$ hexdump -C umlaut-iso88591.txt 
00000000  e4 0a                                             |..|
00000002
$ hexdump -C umlaut-utf16.txt 
00000000  ff fe e4 00 0a 00                                 |......|
00000006

Créez quelque chose d'invalide en mélangeant les trois:

$ cat umlaut-iso88591.txt umlaut-utf8.txt umlaut-utf16.txt > umlaut-mixed.txt 

Ce qui filedit:

$ file -i *
umlaut-iso88591.txt: text/plain; charset=iso-8859-1
umlaut-mixed.txt:    application/octet-stream; charset=binary
umlaut-utf16.txt:    text/plain; charset=utf-16le
umlaut-utf8.txt:     text/plain; charset=utf-8

sans -i:

$ file *
umlaut-iso88591.txt: ISO-8859 text
umlaut-mixed.txt:    data
umlaut-utf16.txt:    Little-endian UTF-16 Unicode text, with no line terminators
umlaut-utf8.txt:     UTF-8 Unicode text

La filecommande n'a aucune idée de "valide" ou "invalide". Il ne voit que quelques octets et essaie de deviner ce que l'encodage pourrait être. En tant qu'êtres humains, nous pourrions être en mesure de reconnaître qu'un fichier est un fichier texte avec quelques trémas dans un "mauvais" codage. Mais en tant qu'ordinateur, il aurait besoin d'une sorte d'intelligence artificielle.

On pourrait soutenir que l'heuristique de fileest une sorte d'intelligence artificielle. Pourtant, même si c'est le cas, il s'agit d'un projet très limité.

Voici plus d'informations sur la filecommande: http://www.linfo.org/file_command.html

lesmana
la source
Merci, cela a fonctionné ... J'avais essayé 'file , but without any option :( ... I've now also tried a mixof UTF-16 and UTF-8 and ISO-8859-1. file -i` rapporté unknown-8bit. Donc, cela semble aussi être la réponse à: "Comment détecter un encodage invalide / inconnu"
Peter.O
Pour ceux qui arrivent ici et qui sont sur mac, c'est file -Iavec un «i» majuscule au lieu de minuscule.
samuraiseoul
21

Il n'est pas toujours possible de savoir avec certitude quel est l'encodage d'un fichier texte. Par exemple, la séquence d'octets \303\275( c3 bden hexadécimal) peut être ýen UTF-8, ou ýen latin1, ou Ă˝en latin2, ou en BIG-5, etc.

Certains encodages ont des séquences d'octets non valides, il est donc possible de les écarter. Cela est vrai en particulier pour UTF-8; la plupart des textes dans la plupart des encodages 8 bits ne sont pas valides UTF-8. Vous pouvez tester UTF-8 valide avec isutf8de moreutils ou avec iconv -f utf-8 -t utf-8 >/dev/null, entre autres.

Il existe des outils qui tentent de deviner l'encodage d'un fichier texte. Ils peuvent faire des erreurs, mais ils fonctionnent souvent dans la pratique tant que vous n'essayez pas délibérément de les duper.

  • file
  • PerlEncode::Guess (partie de la distribution standard) tente des encodages successifs sur une chaîne d'octets et renvoie le premier encodage dans lequel la chaîne est un texte valide.
  • Enca est un convertisseur de devinette et d’encodage. Vous pouvez lui attribuer un nom de langue et du texte que vous présumez être dans cette langue (les langues prises en charge sont principalement les langues d'Europe de l'Est), et il essaie de deviner le codage.

S'il y a des métadonnées (HTML / XML charset=, TeX \inputenc, emacs -*-coding-*-,…) dans le fichier, les éditeurs avancés comme Emacs ou Vim sont souvent en mesure d'analyser ces métadonnées. Ce n'est pas facile à automatiser à partir de la ligne de commande cependant.

Gilles, arrête de faire le mal
la source
Merci pour la bonne vue d'ensemble ... Oui, "la meilleure estimation" peut être la seule option lorsque l'encodage n'est pas connu ... À l'aide de iconv, je viens d'exécuter tous les 1168 encodages (y compris les alias) répertoriés par l' iconv -lun de mes fichiers .htm. ... Il y a eu 683 encodages qui ont réussi à rassembler .. Le jeu de caractères actuel du fichier = ISO-8859-1 .. composé de toutes les valeurs de la plage ASCII de la barre une .. Le caractère non-ASCII était \ xA9.
Peter.O
0

Aussi au cas où vous classez -i vous donne inconnu

Vous pouvez utiliser cette commande php qui peut deviner un jeu de caractères comme ci-dessous:

En php, vous pouvez vérifier comme ci-dessous:

Spécifier explicitement la liste de codage:

php -r "echo 'probably : ' . mb_detect_encoding(file_get_contents('myfile.txt'), 'UTF-8, ASCII, JIS, EUC-JP, SJIS, iso-8859-1') . PHP_EOL;"

" Mb_list_encodings " plus précis :

php -r "echo 'probably : ' . mb_detect_encoding(file_get_contents('myfile.txt'), mb_list_encodings()) . PHP_EOL;"

Ici, dans le premier exemple, vous pouvez voir que je mets une liste de codages (détection de la liste) susceptibles de correspondre. Pour obtenir un résultat plus précis, vous pouvez utiliser tous les encodages possibles via: mb_list_encodings ()

Remarque les fonctions mb_ * nécessitent php-mbstring

apt-get install php-mbstring 

Voir la réponse: https://stackoverflow.com/a/57010566/3382822

Mohamed23gharbi
la source