【发布时间】:2009-11-13 17:53:34
【问题描述】:
如何检查 shell 脚本中的文件编码? 我需要知道文件是用 utf-8 还是 iso-8859-1 编码的。
谢谢
【问题讨论】:
如何检查 shell 脚本中的文件编码? 我需要知道文件是用 utf-8 还是 iso-8859-1 编码的。
谢谢
【问题讨论】:
我只是用
file -bi myfile.txt
确定特定文件的字符编码。
一种具有外部依赖的解决方案,但我怀疑file 现在在所有半现代发行版中非常普遍。
编辑:
作为对 Laurence Gonsalves 评论的回应:b 是“简要”选项(不包括文件名),i 是 --mime 的简写形式,因此是最便携的方式(包括 Mac OSX ) 那么可能是:
file --mime myfile.txt
【讨论】:
file -bi 在 Linux 上为我工作,但在 OS-X 上不行。在 OS-X 上,无论编码如何,它都会显示“常规文件”。 file --mime 或只是 file 没有标志适用于 OS-X 和 Linux。
Windows-1250 编码的文件上获取unknown-8bit
没有办法 100% 确定(除非您处理的是内部声明其编码的文件格式)。
大多数尝试进行这种区分的工具都会尝试将文件解码为 utf-8(因为这是更严格的编码),如果失败,则回退到 iso-8859-1。您可以使用iconv“手动”执行此操作,也可以使用file:
$ file utf8.txt
utf8.txt: UTF-8 Unicode text
$ file latin1.txt
latin1.txt: ISO-8859 text
请注意,ASCII 文件同时兼容 UTF-8 和 ISO-8859-1。
$ file ascii.txt
ascii.txt: ASCII text
最后:例如,没有真正的方法可以区分 ISO-8859-1 和 ISO-8859-2,除非您假设它是自然语言并使用统计方法。这可能就是文件显示“ISO-8859”的原因。
【讨论】:
你可以使用文件命令
file --mime myfile.text
【讨论】:
文件命令不是 100% 确定的。简单测试:
#!/bin/bash
echo "a" > /tmp/foo
for i in {1..1000000}
do
echo "asdas" >> /tmp/foo
done
echo "üöäÄÜÖß " >> /tmp/foo
file -b --mime-encoding /tmp/foo
这个输出:
us-ascii
Ascii 不知道德语变音符号。
文件是一堆字节(字节序列)。如果不信任元数据(BOM 仅推荐用于 utf-16 和 utf-32、MIME、数据标头),您将无法真正检测到编码。字节序列可以解释为 utf-8 或 ISO-8859-1/2 或任何你想要的。好吧,如果存在 iso-8850-1/utf-8 映射,这取决于特定的序列。您想要的是将整个文件内容编码为所需的字符编码。如果失败,则所需的编码没有此字节序列的映射。
在 shell 中可能使用 python、perl 或像 Laurence Gonsalves 所说的 iconv。对于我在 python 中使用的文本文件:
f = codecs.open(path, encoding='utf-8', errors='strict')
def valid_string(str):
try:
str.decode('utf-8')
return True
except UnicodeDecodeError:
return False
你怎么知道一个文件是一个文本文件。你没有。您使用所需的字符编码逐行编码。好的,你可以加一点信任,检查BOM是否存在(文件是utf编码的)。
【讨论】: