Как я могу проверить кодировку текстового файла… Является ли она допустимой, и какой она?

Вопрос или проблема

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

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

Когда информация о кодировке просто недоступна, есть ли программа CLI, которая может сделать “наилучшую догадку” о том, какая кодировка может подойти?

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

Команда file делает “наилучшие догадки” о кодировке.

Здесь это продемонстрировано на файле, содержащем немецкий умлаут, закодированный в utf-8:

$ file umlaut-utf8.txt
umlaut-utf8.txt:     UTF-8 Unicode text

(см. ниже, как я создал файлы)

Тот же умлаут в двух других кодировках:

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

Все три вместе для недопустимой кодировки:

$ file umlaut-mixed.txt
umlaut-mixed.txt:    data

Вы можете использовать параметр -i для вывода в типе mime:

$ 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

(на mac это -I, потому что разработчики Apple думают по-другому.)

Команда file довольно ограничена. Она смотрит на некоторые байты и пытается угадать, какая кодировка может быть. Если она распознает паттерн, она скажет, что это та или иная кодировка. Если паттерн не распознается или если распознанные паттерны противоречат друг другу, она скажет “data” (или binary в типе mime). Что практически означает, что валидная кодировка не распознана.

Это похоже на то, как вы могли бы распознать текст как испанский или французский на основе распределения символов и умлаутов. Если вам был дан текст, в котором распределение символов не имеет смысла, вы могли бы заключить, что это “недопустимый” текст. Но это может быть язык, который вы просто раньше не видели. Сравните это с Lorem Ipsum. Текст, созданный для того, чтобы выглядеть как натуральный текст, но на самом деле является бессмыслицей: https://en.wikipedia.org/wiki/Lorem_ipsum

Вот пример, где file не смог распознать правильную кодировку: просмотреть файл, содержащий текст DOS (символы рисования коробки, терминаторы строк CRLF) и escape-последовательности

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


Как я создавал файлы:

$ echo ä > umlaut-utf8.txt

Вы можете скопировать эту строку и выполнить ее. Это должно создать файл, содержащий умлаут в utf8.

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

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

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

$ 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

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

Создайте что-то “недопустимое”, смешав все три:

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

Не всегда возможно точно узнать, какая кодировка у текстового файла. Например, последовательность байтов \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
  • Perl Encode::Guess (часть стандартной дистрибуции) пробует последовательные кодировки на байтовой строке и возвращает первую кодировку, в которой строка является допустимым текстом.
  • Enca — это гадалка кодировок и конвертер. Вы можете дать ей имя языка и текст, который вы предполагаете на этом языке (поддерживаемые языки в основном восточноевропейские языки), и она попытается угадать кодировку.

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

Я думаю, что этот инструмент CLI может сделать именно то, что вы искали!

Убедитесь, что у вас установлены Node.js и NPM:

$ sudo apt install nodejs npm

Установите CLI:

$ npm install -g detect-file-encoding-and-language

Используйте CLI:

$ dfeal "/home/user name/Documents/subtitle file.srt"
# Возможный результат: { language: french, encoding: CP1252, confidence: 0.99 }

Также в случае, если file -i дает вам unknown

Вы можете использовать эту 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

Ответ или решение

Как протестировать кодировку текстового файла: определение валидности и типа кодировки

Работа с текстовыми файлами в различных кодировках может создать определенные трудности, особенно если информация о кодировке отсутствует. В этой статье мы рассмотрим методы тестирования кодировки текстового файла, включая определение его валидности и определение типа кодировки. Мы также ознакомимся с несколькими эффективными инструментами, доступными как в командной строке (CLI), так и через программирование.

Основные понятия кодировки текстовых файлов

Кодировка определяет, как символы текста представлены в битах. Наиболее распространенные кодировки включают UTF-8, ISO-8859-1, UTF-16 и другие. Отсутствие информации о кодировке может привести к неправильному отображению текста, ложным предупреждениям о недопустимой кодировке или даже повреждению данных.

Как тестировать кодировку текстового файла

  1. Использование команды file

    Команда file в Unix-подобных системах может помочь определить кодировку текстового файла. Она выполняет анализ байтов и делает "наилучшие предположения" о кодировке. Например:

    file имя_файла.txt

    Использование параметра -i выводит результат в формате MIME:

    file -i имя_файла.txt

    Пример вывода:

    имя_файла.txt: text/plain; charset=utf-8
  2. Проверка на валидность кодировки

    Если вы знаете, какая кодировка должна использоваться, можно проверить её валидность. Например, для UTF-8 можно использовать iconv:

    iconv -f utf-8 -t utf-8 имя_файла.txt > /dev/null

    Ошибки в этом процессе укажут на недопустимую кодировку.

    Альтернативой является использование утилиты isutf8 из пакета moreutils:

    isutf8 имя_файла.txt
  3. Гадание кодировки с помощью специализированных инструментов

    Существуют CLI-инструменты, способные догадаться о кодировке. Вот некоторые из них:

    • enca — инструмент для угадывания кодировки, поддерживающий несколько языков, в основном восточноевропейских.
    • DetectFileEncoding — утилита на Node.js, позволяющая обнаруживать кодировку и язык файла:
    npm install -g detect-file-encoding-and-language
    dfeal имя_файла.txt
  4. Использование PHP для определения кодировки

    Если у вас установлен PHP, вы можете использовать функции mbstring для определения кодировки:

    php -r "echo mb_detect_encoding(file_get_contents('myfile.txt'), 'UTF-8, ISO-8859-1');"

    Чтобы получить результаты, используя все доступные кодировки:

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

    Убедитесь, что установлено расширение PHP mbstring:

    apt-get install php-mbstring

Заключение

Тестирование кодировки текстового файла может быть затруднительным из-за многообразия кодировок и возможных недочетов в представлении текста. Используя описанные методы и инструменты, вы сможете эффективно определять и проверять кодировку ваших текстовых файлов. Если кодировка отсутствует или ситуация становится слишком сложной, не стесняйтесь использовать несколько методов вместе для получения наиболее точного результата.

Оцените материал
Добавить комментарий

Капча загружается...