如何确定OSX中的文件编码?

我试图在TextMate中input一些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} 。)

我find了iconv ,但是似乎没有办法告诉我编码是什么 – 它只会转换一次,我知道了。

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

没有确定的方法来检测文件的编码。 阅读这个答案,它解释了为什么。

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

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

 file -I {filename} 

在Mac OS X中,只要您正在testing的文件包含基本ASCII范围之外的字符,命令file -I (大写i)就会给您适当的字符集。

例如,如果你进入terminal,并使用vi创build一个文件,例如。 vi test.txt然后插入一些字符并包含重音字符(尝试ALT-e,然后按e),然后保存该文件。

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

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

您还可以使用以下命令从一种文件types转换为另一种文件types:

 iconv -f original_charset -t new_charset originalfile > newfile 

例如

 iconv -f utf-16le -t utf-8 file1.txt > file2.txt 
 vim -c 'execute "silent !echo " . &fileencoding | q' {filename} 

别名在我的bashconfiguration中

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

所以我只是打字

 vic {filename} 

在我的香草OSX优胜美地,它比“文件-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 

只要使用:

 file -I <filename> 

而已。

使用带有--mime-encoding选项的file命令(例如, file --mime-encoding some_file.txt )而不是-I选项可以在OS X上使用,并且省略了MIMEtypes“text / plain”,你可能不关心。

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

在terminal中键入file myfile.tex有时可以使用一系列algorithm和幻数来告诉您文件的编码和types。 这是相当有用的,但不要依靠它提供具体或可靠的信息。

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

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

您可以尝试加载文件到Firefox窗口,然后去查看 – 字符编码。 该文件的编码types旁边应该有一个复选标记。

你使用哪种LaTeX? 当我使用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) (但它是相当有限的),但像其他人说,这是困难的。

检查编码的蛮力方法可能只是检查hex编辑器或类似的文件。 (或者写一个程序来检查)看文件中的二进制数据。 UTF-8格式相当容易识别。 所有ASCII字符都是单个字节,值低于128(0x80)多字节序列遵循维基文章中显示的模式

如果你能find一个简单的方法来让你的程序来validation你的编码,那显然是一个捷径,但是如果一切都失败了,这将会成功。

我很懒。 我只是使用崇高的文字来切换编码。

我在下面实现了bash脚本,它适用于我。

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

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

如果使用这个脚本的结果是“坏事”,不要责怪我。 那里有一个rm -f ,所以有怪物。 我试图通过在随机后缀的文件上使用它来防止不利影响,但我没有做出任何承诺。

testing达尔文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