Как определить кодировку файла в OSX?

Я пытаюсь ввести некоторые символы UTF-8 в файл LaTeX в TextMate (который говорит, что его кодировка по умолчанию - UTF-8), но LaTeX, кажется, не понимает их. Бег cat my_file.tex показывает символы правильно в терминале. Бег ls -al показывает то, что я никогда раньше не видел: "@" в списке файлов:

-rw-r--r--@  1 me      users      2021 Feb 11 18:05 my_file.tex

(И да, я использую \usepackage[utf8]{inputenc} в латексе.)

я обнаружил iconv, но это, кажется, не в состоянии сказать мне, что такое кодировка - она ​​будет преобразована только когда я это выясню.

15 ответов

Решение

@ означает, что файл имеет расширенные атрибуты файла, связанные с ним. Вы можете запросить их, используя getxattr() функция.

Нет определенного способа определить кодировку файла. Прочтите этот ответ, он объясняет почему.

Есть инструмент командной строки, enca, который пытается угадать кодировку. Вы можете проверить это.

С использованием -I (это заглавная i) опция в команде file, кажется, показывает кодировку файла.

file -I {filename}

В Mac OS X команда file -I (заглавная i) даст вам правильный набор символов, если тестируемый файл содержит символы вне основного диапазона ASCII.

Например, если вы заходите в Терминал и используете vi для создания файла, например. vi test.txtзатем вставьте несколько символов и вставьте символ с акцентом (попробуйте ALT-e, а затем e), затем сохраните файл.

Они печатают file -I text.txt и вы должны получить такой результат:

test.txt: text/plain; charset=utf-8

vim -c 'execute "silent !echo " . &fileencoding | q' {filename}

где-то в моей конфигурации bash

alias vic="vim -c 'execute \"silent !echo \" . &fileencoding | q'"

так что я просто набираю

vic {filename}

На моем ванильном OSX Yosemite он дает более точные результаты, чем "file -I":

$ file -I pdfs/udocument0.pdf
pdfs/udocument0.pdf: application/pdf; charset=binary
$ vic pdfs/udocument0.pdf
latin1
$
$ file -I pdfs/t0.pdf
pdfs/t0.pdf: application/pdf; charset=us-ascii
$ vic pdfs/t0.pdf
utf-8

Вы также можете конвертировать из одного типа файла в другой, используя следующую команду:

iconv -f original_charset -t new_charset originalfile > newfile

например

iconv -f utf-16le -t utf-8 file1.txt > file2.txt

Просто используйте:

file -I <filename>

Вот и все.

С помощью file команда с --mime-encoding вариант (например, file --mime-encoding some_file.txt) вместо опции -I работает в OS X и имеет дополнительное преимущество - опущен тип mime, "text/plain", который вам, вероятно, не важен.

Классический 8-битный LaTeX очень ограничен, в котором могут использоваться символы UTF8; это сильно зависит от кодировки шрифта, который вы используете, и от того, какие глифы у этого шрифта есть в наличии.

Поскольку вы не приводите конкретный пример, трудно точно определить, в чем проблема - пытаетесь ли вы использовать глиф, которого нет в вашем шрифте, или не используете правильную кодировку шрифта в первом место.

Вот минимальный пример, показывающий, как несколько символов UTF8 могут использоваться в документе LaTeX:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage[utf8]{inputenc}
\begin{document}
‘Héllø—thêrè.’
\end{document}

Возможно, вам повезет больше с кодировкой [utf8x], но следует немного предупредить, что она больше не поддерживается и имеет некоторые особенности по сравнению с [utf8] (насколько я помню; с тех пор, как я на нее посмотрел, прошло довольно много времени). Но если это поможет, это все, что имеет значение для вас.

Знак @ означает, что файл имеет расширенные атрибуты. xattr file показывает, какие атрибуты у него есть, xattr -l file также показывает значения атрибутов (которые иногда могут быть большими - попробуйте, например, xattr /System/Library/Fonts/HelveLTMM чтобы увидеть шрифт старого стиля, который существует в ветке ресурсов).

Typing file myfile.tex В терминале иногда можно узнать кодировку и тип файла, используя серию алгоритмов и магических чисел. Это довольно полезно, но не полагайтесь на него, предоставляя конкретную или надежную информацию.

Localizable.strings Файл (найденный в локализованных приложениях Mac OS X) обычно считается исходным файлом UTF-16 C.

Synalyze It! позволяет сравнивать текст или байты во всех кодировках, которые предлагает библиотека ICU. Используя эту функцию, вы обычно сразу видите, какая кодовая страница имеет смысл для ваших данных.

Я реализовал скрипт bash ниже, он работает для меня.

Сначала пытается iconv из кодировки, возвращаемой file --mime-encoding в utf-8,

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

Если в результате использования этого скрипта произойдут "плохие вещи", не вините меня. Есть rm -f там, так что там будут монстры. Я пытался предотвратить негативные последствия, используя его для файлов со случайным суффиксом, но я не даю никаких обещаний.

Проверено на Дарвине 15.6.0.

#!/bin/bash

if [[ $# -lt 1 ]]
then
  echo "ERROR: need one input argument: file of which the enconding is to be detected."
  exit 3
fi

if [ ! -e "$1" ]
then
  echo "ERROR: cannot find file '$1'"
  exit 3
fi

if [[ $# -ge 2 ]]
then
  MAX_DIFF_LINES=$2
else
  MAX_DIFF_LINES=10
fi


#try the easy way
ENCOD=$(file --mime-encoding $1 | awk '{print $2}')
#check if this enconding is valid
iconv -f $ENCOD -t utf-8 $1 &> /dev/null
if [ $? -eq 0 ]
then
  echo $ENCOD
  exit 0
fi

#hard way, need the user to visually check the difference between the original and re-encoded files
for i in $(iconv -l | awk '{print $1}')
do
  SINK=$1.$i.$RANDOM
  iconv -f $i -t utf-8 $1 2> /dev/null > $SINK
  if [ $? -eq 0 ]
  then
    DIFF=$(diff $1 $SINK)
    if [ ! -z "$DIFF" ] && [ $(echo "$DIFF" | wc -l) -le $MAX_DIFF_LINES ]
    then
      echo "===== $i ====="
      echo "$DIFF"
      echo "Does that make sense [N/y]"
      read $ANSWER
      if [ "$ANSWER" == "y" ] || [ "$ANSWER" == "Y" ]
      then
        echo $i
        exit 0
      fi
    fi
  fi
  #clean up re-encoded file
  rm -f $SINK
done

echo "None of the encondings worked. You're stuck."
exit 3

Вы можете попробовать загрузить файл в окно Firefox, а затем перейти к View - Character Encoding. Рядом с типом кодировки файла должна стоять галочка.

Какой LaTeX вы используете? Когда я использовал teTeX, мне пришлось вручную загружать пакет unicode и добавлять его в мои файлы.tex:

% UTF-8 stuff
\usepackage[notipa]{ucs}
\usepackage[utf8x]{inputenc}
\usepackage[T1]{fontenc}

Теперь я перешел на XeTeX из пакета TeXlive 2008 ( здесь), это еще проще:

% UTF-8 stuff
\usepackage{fontspec}
\usepackage{xunicode}

Что касается определения кодировки файла, вы можете играть с file(1) (но это довольно ограничено), но, как сказал кто-то еще, это сложно.

Простой способ проверить кодировку может просто проверить файл в шестнадцатеричном редакторе или аналогичном. (или напишите программу для проверки) Посмотрите на двоичные данные в файле. Формат UTF-8 довольно легко распознать. Все символы ASCII являются однобайтовыми со значениями ниже 128 (0x80). Многобайтовые последовательности следуют шаблону, показанному в статье вики.

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

Другие вопросы по тегам