¿Cómo puedo probar la codificación de un archivo de texto ... ¿Es válido y qué es?


46

Tengo varios .htmarchivos que se abren en Gedit sin ninguna advertencia / error, pero cuando abro estos mismos archivos Jedit, me advierte de una codificación UTF-8 no válida ...

La metaetiqueta HTML dice "charset = ISO-8859-1". Jedit permite una Lista de codificaciones de reserva y una Lista de detectores automáticos de codificación (actualmente "BOM XML-PI"), por lo que mi problema inmediato se ha resuelto. Pero esto me hizo pensar: ¿Qué pasaría si los metadatos no estuvieran allí?

Cuando la información de codificación simplemente no está disponible, ¿existe un programa CLI que pueda adivinar qué codificaciones pueden aplicarse?

Y, aunque es un tema ligeramente diferente; ¿Existe un programa CLI que pruebe la validez de una codificación conocida ?


Similar a "¿Cómo detectar automáticamente la codificación de archivos de texto?" superuser.com/questions/301552/...
buzz3791

Respuestas:


60

El filecomando hace "mejores conjeturas" sobre la codificación. Use el -iparámetro para forzar filea imprimir información sobre la codificación.

Demostración:

$ 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

Así es como creé los archivos:

$ echo ä > umlaut-utf8.txt 

Hoy en día todo es utf-8. Pero convéncete a ti mismo:

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

Compare con https://en.wikipedia.org/wiki/Ä#Computer_encoding

Convierte a las otras codificaciones:

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

Verifique el volcado hexadecimal:

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

Crea algo "inválido" mezclando los tres:

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

Lo que filedice:

$ 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

sin -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

El filecomando no tiene idea de "válido" o "inválido". Simplemente ve algunos bytes e intenta adivinar cuál podría ser la codificación. Como humanos, podríamos reconocer que un archivo es un archivo de texto con algunas diéresis en una codificación "incorrecta". Pero como computadora necesitaría algún tipo de inteligencia artificial.

Se podría argumentar que la heurística de filees algún tipo de inteligencia artificial. Sin embargo, incluso si es así, es muy limitado.

Aquí hay más información sobre el filecomando: http://www.linfo.org/file_command.html


Gracias, funcionó ... Intenté 'file , but without any option :( ... I've now also tried a mixof UTF-16 and UTF-8 and ISO-8859-1. file -i` reportado unknown-8bit. Entonces, esta también parece ser la respuesta a: "Cómo detectar una codificación inválida / desconocida"
Peter.O

Para aquellos que llegan aquí y están en Mac, es file -Icon una 'i' mayúscula en lugar de minúsculas.
samuraiseoul

21

No siempre es posible averiguar con certeza cuál es la codificación de un archivo de texto. Por ejemplo, la secuencia de bytes \303\275( c3 bden hexadecimal) podría estar ýen UTF-8, o ýen latin1, o Ă˝en latin2, o en BIG-5, y así sucesivamente.

Algunas codificaciones tienen secuencias de bytes no válidas, por lo que es posible descartarlas con seguridad. Esto es cierto en particular de UTF-8; La mayoría de los textos en la mayoría de las codificaciones de 8 bits no son válidos UTF-8. Puede probar para UTF-8 válidos con isutf8de moreutils o con iconv -f utf-8 -t utf-8 >/dev/null, entre otros.

Hay herramientas que intentan adivinar la codificación de un archivo de texto. Pueden cometer errores, pero a menudo funcionan en la práctica siempre que no intentes engañarlos deliberadamente.

  • file
  • PerlEncode::Guess (parte de la distribución estándar) intenta codificaciones sucesivas en una cadena de bytes y devuelve la primera codificación en la que la cadena es texto válido.
  • Enca es un adivinador y convertidor de codificación. Puede darle un nombre de idioma y un texto que presume que está en ese idioma (los idiomas admitidos son en su mayoría idiomas de Europa del Este) e intenta adivinar la codificación.

Si hay metadatos (HTML / XML charset=, TeX \inputenc, emacs -*-coding-*-, ...) en el archivo, los editores avanzados como Emacs o Vim a menudo pueden analizar esos metadatos. Sin embargo, eso no es fácil de automatizar desde la línea de comandos.


Gracias por la buena visión general ... Sí, "best-guess" puede ser la única opción cuando no se conoce la codificación ... Utilizando iconv, acabo de ejecutar todas las 1168 codificaciones (incluidos los alias) que figuran en iconv -luno de mis archivos .htm ... Hubo 683 codificaciones que pasaron la lista ... El conjunto de caracteres real del archivo = ISO-8859-1 ... compuesto por todos los valores de rango ASCII de la barra uno ... El carácter no ASCII fue \ xA9.
Peter.O

0

También en caso de que archives -i te da desconocido

Puede usar este comando php que puede adivinar el conjunto de caracteres como a continuación:

En php puedes marcar como a continuación:

Especificando la lista de codificación explícitamente:

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 " más precisos :

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

Aquí, en el primer ejemplo, puede ver que pongo una lista de codificaciones (detectar el orden de la lista) que podrían coincidir. Para obtener un resultado más preciso, puede usar todas las codificaciones posibles a través de: mb_list_encodings ()

Nota: las funciones mb_ * requieren php-mbstring

apt-get install php-mbstring 

Ver respuesta: https://stackoverflow.com/a/57010566/3382822

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.