it-swarm-ru.tech

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

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

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

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

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

55
Peter.O

Команда 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

70
lesmana

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

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

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

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

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

22
Gilles 'SO- stop being evil'

Также в случае, если вы подаете -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

1
Mohamed23gharbi