Как проверить кодировку файла в оболочке script? Мне нужно знать, закодирован ли файл в utf-8 или iso-8859-1.
Спасибо
Как проверить кодировку файла в оболочке script? Мне нужно знать, закодирован ли файл в utf-8 или iso-8859-1.
Спасибо
Я бы просто использовал
file -bi myfile.txt
чтобы определить кодировку символов для определенного файла.
Решение с внешней зависимостью, но я подозреваю, что file
очень часто встречается среди всех полусовременных дистрибутивов.
EDIT:
Как ответ на комментарий Лоуренса Гонсальва: b
- это вариант быть "кратким" (не включать имя файла), а i
- сокращенный эквивалент --mime
, поэтому самый переносимый способ (включая Mac OSX), то, вероятно, это:
file --mime myfile.txt
Невозможно быть на 100% уверенным (если вы не имеете дело с файловым форматом, который внутренне указывает его кодировку).
Большинство инструментов, пытающихся сделать это различие, будут пытаться и декодировать файл как utf-8 (как это более строгая кодировка), а если это не удается, вернитесь к iso-8859-1. Вы можете сделать это с помощью iconv
"вручную", или вы можете использовать file
:
$ file utf8.txt
utf8.txt: UTF-8 Unicode text
$ file latin1.txt
latin1.txt: ISO-8859 text
Обратите внимание, что файлы ASCII совместимы как с UTF-8, так и с ISO-8859-1.
$ file ascii.txt
ascii.txt: ASCII text
Наконец: нет реального способа отличить ISO-8859-1 и ISO-8859-2, например, если вы не собираетесь считать его естественным языком и использовать статистические методы. Вероятно, поэтому файл говорит "ISO-8859".
вы можете использовать команду file
file --mime myfile.text
Команда File не соответствует 100%. Простой тест:
#!/bin/bash
echo "a" > /tmp/foo
for i in {1..1000000}
do
echo "asdas" >> /tmp/foo
done
echo "üöäÄÜÖß " >> /tmp/foo
file -b --mime-encoding /tmp/foo
эти выходы:
us-ascii
Ascii не знает немецких умляутов.
Файл представляет собой кучу байтов (последовательность байтов). Не доверяя метаданным (спецификация только для utf-16 и utf-32, MIME, заголовок данных), вы не можете действительно обнаружить кодировку. Последовательность байтов может быть интерпретирована как utf-8 или ISO-8859-1/2 или что угодно. Ну, это зависит от определенной последовательности, если существует карта iso-8850-1/utf-8. Вы хотите закодировать весь контент файла на нужную кодировку. Если это не удается, требуемая кодировка не имеет карты для этой последовательности байтов.
В оболочке возможно использовать python, perl или, как говорит Laurence Gonsalves, iconv. Для текстовых файлов я использую в python следующее:
f = codecs.open(path, encoding='utf-8', errors='strict')
def valid_string(str):
try:
str.decode('utf-8')
return True
except UnicodeDecodeError:
return False
Как вы, что файл является текстовым файлом. Вы этого не сделаете. Вы кодируете строку за строкой с нужной кодировкой символов. Хорошо, вы можете добавить немного доверия и проверить, существует ли спецификация (файл закодирован в utf).