我如何确定文件编码在OS X?

我试图在TextMate软件中输入一些UTF-8字符到LaTeX文件中(它说它的默认编码是UTF-8),但LaTeX似乎不理解它们。

运行cat my_file.tex可以在Terminal中正确显示字符。运行ls -al会显示一些我以前从未见过的东西:文件列表旁边的“@”:

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

(是的,我在LaTeX中使用\usepackage[utf8]{inputenc}。)

我已经找到iconv,但这似乎不能告诉我编码是什么-它只会转换一旦我弄清楚。

241900 次浏览

@表示该文件具有与之相关的扩展文件属性。你可以使用getxattr()函数查询它们。

没有确定的方法来检测文件的编码。阅读答案,它解释了原因。

有一个命令行工具enca,它尝试猜测编码。你可能会想去看看。

你用的是哪种乳胶?当我使用teTeX时,我必须手动下载unicode包,并将其添加到我的.tex文件中:

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

现在,我已经从TeXlive 2008包(在这里)切换到XeTeX,它甚至更简单:

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

至于检测文件的编码,你可以使用file(1)(但它相当有限),但就像其他人说的,这是困难的。

一种强制检查编码的方法可能只是在十六进制编辑器或类似工具中检查文件。(或编写程序检查)查看文件中的二进制数据。UTF-8格式相当容易识别。所有ASCII字符都是单字节,值低于128 (0x80) 多字节序列遵循维基百科的文章

所示的模式

如果您能找到一种更简单的方法来让程序为您验证编码,这显然是一种捷径,但如果所有其他方法都失败了,那么这个方法就可以了。

经典的8位LaTeX只能使用UTF8字符;它高度依赖于您所使用的字体的编码以及该字体具有哪些可用的字形。

由于您没有给出具体的示例,因此很难确切地知道问题在哪里——您是否试图使用字体没有的字形,或者您是否首先就没有使用正确的字体编码。

下面是一个演示如何在LaTeX文档中使用几个UTF8字符的最小示例:

\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来查看存在于资源分支中的旧式字体)。

在终端中输入file myfile.tex有时可以通过一系列算法和神奇数字告诉你文件的编码和类型。它相当有用,但不要依赖它提供具体或可靠的信息。

Localizable.strings文件(在本地化的Mac OS X应用程序中找到)通常被报告为utf - 16c源文件。

file命令上使用-I(这是一个大写i)选项似乎显示了文件编码。

file -I {filename}

只使用:

file -I <filename>

就是这样。

在Mac OS X中,命令file -I(大写i)将为您提供适当的字符集,只要您正在测试的文件包含基本ASCII范围之外的字符。

例如,如果你进入终端,使用vi来创建一个文件。vi test.txt 然后插入一些字符,包括一个重音字符(尝试ALT-e后面跟着e)

. txt文件

它们输入file -I text.txt,你应该得到这样的结果:

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

你也可以使用下面的命令从一个文件类型转换到另一个文件类型:

iconv -f original_charset -t new_charset originalfile > newfile

如。

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

Synalyze它!允许比较ICU库提供的所有编码中的文本或字节。使用该功能,您通常会立即看到哪个代码页对您的数据有意义。

您可以尝试将文件加载到firefox窗口中,然后转到“查看-字符编码”。在文件的编码类型旁边应该有一个复选标记。

使用file命令和--mime-encoding选项(例如file --mime-encoding some_file.txt)而不是-I选项在OS X上工作,并且有省略mime类型“text/plain”的额外好处,这可能是你不关心的。

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

在我的bash配置中的某个地方别名为

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

所以我就输入

vic {filename}

在我的香草OSX Yosemite上,它产生的结果比“文件- 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

我实现了下面的bash脚本,它为我工作。

它首先尝试从file --mime-encoding返回到utf-8的编码中iconv

如果失败,它将遍历所有编码,并显示原始文件和重新编码的文件之间的差异。它会跳过产生较大diff输出的编码("large"由MAX_DIFF_LINES变量或第二个输入参数定义),因为这些编码很可能是错误的。

如果使用这个脚本导致了“不好的事情”,不要责怪我。里面有rm -f,所以里面有怪物。我试图通过对带有随机后缀的文件使用它来防止不良影响,但我不做任何承诺。

在Darwin 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