кодирование сценария оболочки файла - PullRequest
33 голосов
/ 13 ноября 2009

Как проверить кодировку файла в скрипте оболочки? Мне нужно знать, закодирован ли файл в utf-8 или iso-8859-1.

Спасибо

Ответы [ 4 ]

58 голосов
/ 13 ноября 2009

Я бы просто использовал

file -bi myfile.txt

для определения кодировки символов конкретного файла.

Решение с внешней зависимостью, но я подозреваю, что file очень распространено в настоящее время среди всех полу-современных дистрибутивов.

EDIT:

В ответ на комментарий Лоуренса Гонсалвеса: b является опцией «краткой» (не включая имя файла), а i является сокращенным эквивалентом --mime, поэтому наиболее переносимым способом (включая Mac OSX ) тогда, вероятно, это:

file --mime myfile.txt 
9 голосов
/ 13 ноября 2009

Невозможно быть на 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».

8 голосов
/ 13 ноября 2009

вы можете использовать команду файла file --mime myfile.text

4 голосов
/ 07 января 2013

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

Асия не знает немецких умлаутов.

Файл представляет собой набор байтов (последовательность байтов). Без доверия к метаданным (спецификация только для utf-16 и utf-32, MIME, заголовок данных) вы не сможете обнаружить кодировку. Последовательность байтов может быть интерпретирована как utf-8 или ISO-8859-1 / 2 или как угодно. Ну, это зависит от определенной последовательности, если карта iso-8850-1 / utf-8 существует. То, что вы хотите, это закодировать все содержимое файла в нужную кодировку символов. В случае неудачи желаемое кодирование не имеет карты для этой последовательности байтов.

В оболочке возможно использовать python, perl или как говорит Лоуренс Гонсалвес 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).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...