Как определить кодировку файла в 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
команда с --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). Многобайтовые последовательности следуют шаблону, показанному в статье вики.
Если вы можете найти более простой способ заставить программу проверить кодировку для вас, это, очевидно, быстрый путь, но если все остальное не сработает, это поможет.