Как я могу проверить кодировку текстового файла ... Это действительно, и что это?

46

У меня есть несколько .htmфайлов, которые открываются в Gedit без каких-либо предупреждений / ошибок, но когда я открываю эти же файлы Jedit, он предупреждает меня о недопустимой кодировке UTF-8 ...

В метатеге HTML указано «charset = ISO-8859-1». Jedit допускает Список резервных кодировок и Список авто-детекторов кодирования (в настоящее время "BOM XML-PI"), поэтому моя непосредственная проблема была решена. Но это заставило меня задуматься: а что если метаданных там не было?

Когда информация о кодировке просто недоступна, существует ли программа CLI, которая может сделать «предположение» о том, какие кодировки могут применяться?

И, хотя это немного другая проблема; есть программа CLI, которая проверяет правильность известной кодировки?

Peter.O
источник
Аналогично «Как автоматически определять кодировку текстового файла?» superuser.com/questions/301552/…
buzz3791
См. Также stackoverflow.com/q/805418/821436 :-)
Восстановить Монику - М. Шредер

Ответы:

60

Команда fileделает "лучшие предположения" о кодировке. Используйте -iпараметр для принудительной fileпечати информации о кодировке.

Демонстрация:

$ 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

Вот как я создал файлы:

$ echo ä > umlaut-utf8.txt 

В настоящее время все является UTF-8. Но убедите себя:

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

Сравните с https://en.wikipedia.org/wiki/Ä#Computer_encoding

Преобразовать в другие кодировки:

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

Проверьте шестнадцатеричный дамп:

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

Создайте что-то «недействительное», смешав все три:

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

Что fileговорит:

$ 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

без -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

Команда fileне имеет понятия «действительный» или «недействительный». Он просто видит несколько байтов и пытается угадать, какой может быть кодировка. Как люди, мы можем понять, что файл - это текстовый файл с некоторыми умлаутами в «неправильной» кодировке. Но в качестве компьютера ему понадобится какой-нибудь искусственный интеллект.

Можно утверждать, что эвристика file- это своего рода искусственный интеллект. Тем не менее, даже если это так, это очень ограниченный.

Вот дополнительная информация о fileкоманде: http://www.linfo.org/file_command.html

lesmana
источник
Спасибо, это сработало ... Я пробовал , but without any option :( ... I've now also tried a mixof UTF-16 and UTF-8 and ISO-8859-1. сообщать "file file -i" unknown-8bit. Таким образом, это также, кажется, ответ на вопрос: «Как обнаружить недопустимую / неизвестную кодировку»
Peter.O
Для тех, кто попадает сюда и работает на Mac, он file -Iимеет заглавную букву «i» вместо строчных.
Самурайзул
21

Не всегда можно узнать наверняка, какова кодировка текстового файла. Например, последовательность байтов \303\275( c3 bdв шестнадцатеричном формате) может быть ýв UTF-8, или ýв latin1, или Ă˝в latin2, или в BIG-5, и так далее.

Некоторые кодировки имеют недопустимые последовательности байтов, поэтому их можно исключить наверняка. Это верно, в частности, для UTF-8; большинство текстов в большинстве 8-битных кодировок не являются допустимыми UTF-8. Вы можете проверить действительный UTF-8 с isutf8от moreutils или с iconv -f utf-8 -t utf-8 >/dev/null, среди других.

Есть инструменты, которые пытаются угадать кодировку текстового файла. Они могут ошибаться, но они часто работают на практике, если вы не пытаетесь обмануть их намеренно.

  • file
  • PerlEncode::Guess (часть стандартного дистрибутива) пробует последовательные кодировки в байтовой строке и возвращает первую кодировку, в которой строка является допустимым текстом.
  • Энка является кодировщиком и конвертером. Вы можете дать ему название языка и текст, который, как вы предполагаете, написан на этом языке (поддерживаемые языки в основном восточноевропейские), и он пытается угадать кодировку.

Если в файле есть метаданные (HTML / XML charset=, TeX \inputenc, emacs -*-coding-*-и т. Д.), Расширенные редакторы, такие как Emacs или Vim, часто могут анализировать эти метаданные. Это не так просто автоматизировать из командной строки.

Жиль "ТАК - перестань быть злым"
источник
Спасибо за хороший обзор ... Да, "наилучшее предположение" может быть единственным вариантом, когда кодировка неизвестна ... Используя iconv, я просто запустил все 1168 кодировок (включая псевдонимы), перечисленных в iconv -lодном из моих файлов .htm ... Было проверено 683 кодировки .. Фактическая кодировка файла = ISO-8859-1 ... составлена ​​из всех значений диапазона ASCII для одного столбца. Не-ASCII-символ был \ xA9.
Peter.O
0

Также в случае, если вы подаете -i дает вам неизвестное

Вы можете использовать эту команду php, которая может угадать кодировку, как показано ниже:

В PHP вы можете проверить, как показано ниже:

Указание списка кодировки явно:

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 ":

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

Здесь, в первом примере, вы можете видеть, что я поместил список кодировок (определите порядок списков), которые могут совпадать. Чтобы получить более точный результат, вы можете использовать все возможные кодировки с помощью: mb_list_encodings ()

Обратите внимание, что функции mb_ * требуют php-mbstring

apt-get install php-mbstring 

Смотрите ответ: https://stackoverflow.com/a/57010566/3382822

Mohamed23gharbi
источник