Як я можу перевірити кодування текстового файлу ... Чи дійсно це та що це?


46

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

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

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

І хоча це дещо інше питання; чи існує програма CLI, яка перевіряє дійсність відомого кодування?


Подібно до "Як автоматично виявити кодування текстових файлів?" superuser.com/questions/301552/…
buzz3791

Відповіді:


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


Дякую, що спрацювало ... Я спробував "файл , but without any option :( ... I've now also tried a mixof UTF-16 and UTF-8 and ISO-8859-1. файлу -i" повідомив unknown-8bit. Отже, це також здається відповіддю на тему: "Як виявити кодування недійсного / невідомого"
Peter.O

Для тих, хто потрапляє сюди і перебуває на mac, це file -Iз великої літери замість малих літер.
samuraiseoul

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 (частина стандартного розподілу) пробує послідовні кодування в байт-рядку і повертає перше кодування, в якому рядок є дійсним текстом.
  • Enca - кодувальний відгадник та перетворювач. Ви можете дати йому назву мови та текст, який, на вашу думку, є цією мовою (підтримувані мови - це переважно східноєвропейські мови), і він намагається відгадати кодування.

Якщо у файлі є метадані (HTML / XML charset=, TeX \inputenc, emacs -*-coding-*-,…), такі розширені редактори, як Emacs або Vim, часто можуть проаналізувати ці метадані. Але це непросто автоматизувати з командного рядка.


Дякую за хороший огляд ... Так, "найкраща здогадка" може бути єдиним варіантом, коли кодування не відомо ... Використовуючи iconv, я просто запустив усі 1168 кодування (включаючи псевдоніми), перелічені iconv -lпроти одного з моїх .htm файлів ... Було 683 кодування, які передали лінійку. Фактична діаграма файлу = ISO-8859-1 .. складається з усіх рядків одного значення ASCII-діапазону .. Не-ASCII char було \ xA9.
Пітер.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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.