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

时间:2009-02-11 23:11:05

标签: macos encoding latex utf-8

我正在尝试将一些UTF-8字符输入到TextMate中的LaTeX文件中(其默认编码为UTF-8),但LaTeX似乎并不理解它们。正在运行cat my_file.tex会在终端中正确显示字符。正在运行ls -al会显示我以前从未见过的内容:文件列表中的“@”:

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

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

我找到iconv,但似乎无法告诉我编码是什么 - 它只会在我弄清楚之后转换。

15 个答案:

答案 0 :(得分:418)

在文件命令中使用-I(即大写i)选项似乎显示文件编码。

file -I {filename}

答案 1 :(得分:55)

在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

答案 2 :(得分:33)

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

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

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

答案 3 :(得分:20)

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

iconv -f original_charset -t new_charset originalfile > newfile

e.g。

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

答案 4 :(得分:19)

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

在我的bash配置中将别名替换为

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

所以我只需输入

vic {filename}

在我的vanilla 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

答案 5 :(得分:13)

只需使用:

file -I <filename>

就是这样。

答案 6 :(得分:8)

使用带有file选项的--mime-encoding命令(例如file --mime-encoding some_file.txt)而不是-I选项适用于OS X,并且具有省略mime类型的附加好处,&#34 ; text / plain&#34;,你可能不关心。

答案 7 :(得分:4)

经典的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]相比有一些特性(据我记得;自从我看了以后已经有一段时间了它)。但如果它成功,那对你来说就是最重要的。

答案 8 :(得分:3)

@符号表示文件有extended attributesxattr file显示了它具有的属性,xattr -l file也显示了属性值(有时可能很大 - 尝试使用xattr /System/Library/Fonts/HelveLTMM来查看资源分叉中存在的旧式字体)。

答案 9 :(得分:2)

在终端中键入file myfile.tex有时可以使用一系列算法和幻数来告诉您文件的编码和类型。它非常有用,但不依赖它提供具体或可靠的信息。

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

答案 10 :(得分:1)

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

答案 11 :(得分:1)

您可以尝试将文件加载到firefox窗口,然后转到View - Character Encoding。文件的编码类型旁边应该有一个复选标记。

答案 12 :(得分:0)

你正在使用哪种LaTeX?当我使用teTeX时,我不得不手动下载unicode包并将其添加到我的.tex文件中:

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

现在,我已经从TeXlive 2008软件包(here)切换到XeTeX,它更加简单:

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

对于文件编码的检测,您可以使用file(1)(但它相当有限),但就像其他人说的那样,很难。

答案 13 :(得分:0)

检查编码的强力方法可能只是在十六进制编辑器或类似文件中检查文件。 (或编写要检查的程序)查看文件中的二进制数据。 UTF-8格式很容易识别。所有ASCII字符都是单字节,值低于128(0x80) 多字节序列遵循wiki article

中显示的模式

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

答案 14 :(得分:0)

我在下面实现了bash脚本,它对我有用。

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

如果失败,它将遍历所有编码并显示原始文件和重新编码文件之间的差异。它跳过产生大的diff输出的编码(由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