我正在统一大量文本文件的编码,这些文件随着时间的推移收集在不同计算机上。我主要将 ISO-8859-1 转换为 UTF-8。这很好地转换了一个文件:
recode ISO-8859-1..UTF-8 file.txt
我当然想对所有文件进行自动批处理,而简单地对每个文件运行上述操作会出现一个问题,即已经以 UTF-8 编码的字符,其编码将被破坏。(例如,如果上述重新编码两次,字符 'ä' 原本在 ISO-8859-1 中,在 UTF-8 中显示时将如下所示� -> ä -> ä
:)
我的问题是,什么类型的脚本仅在需要时运行重新编码,即仅适用于尚未采用目标编码的文件(在我的情况下是 UTF-8)?
通过查看 recode 手册页,我无法弄清楚如何执行此类操作。所以我想这可以归结为如何轻松检查文件的编码,或者至少检查它是否是 UTF-8。这个答案意味着您可以使用 recode 识别有效的 UTF-8 文件,但是如何识别呢?任何其他工具也可以,只要我可以在 bash 脚本的条件中使用结果即可……
答案1
这条消息已经很老了,但我认为我可以解决这个问题:
首先创建一个名为需要重新编码:
#!/bin/bash
# Find the current encoding of the file
encoding=$(file -i "$2" | sed "s/.*charset=\(.*\)$/\1/")
if [ ! "$1" == "${encoding}" ]
then
# Encodings differ, we have to encode
echo "recoding from ${encoding} to $1 file : $2"
recode ${encoding}..$1 $2
fi
您可以这样使用它:
recodeifneeded utf-8 file.txt
因此,如果您想递归运行它并将所有 *.txt 文件编码更改为(假设) utf-8 :
find . -name "*.txt" -exec recodeifneeded utf-8 {} \;
我希望这有帮助。
答案2
该脚本改编自harrymc 的想法它有条件地(基于某些 UTF-8 编码的斯堪的纳维亚字符的存在)对一个文件进行重新编码,对我来说似乎效果很好。
$ cat recode-to-utf8.sh
#!/bin/sh
# Recodes specified file to UTF-8, except if it seems to be UTF-8 already
result=`grep -c [åäöÅÄÖ] $1`
if [ "$result" -eq "0" ]
then
echo "Recoding $1 from ISO-8859-1 to UTF-8"
recode ISO-8859-1..UTF-8 $1 # overwrites file
else
echo "$1 was already UTF-8 (probably); skipping it"
fi
(批处理文件当然是一个简单的事情,例如for f in *txt; do recode-to-utf8.sh $f; done
。)
注意::这完全取决于脚本文件本身是否为 UTF-8。这显然是一种非常有限的解决方案,适合我碰巧拥有的文件类型,欢迎添加更好的答案以更通用的方式解决问题。
答案3
UTF-8 对于哪些字节序列有效有严格的规定。这意味着如果数据可以是 UTF-8,如果你假设它是。
因此你可以做这样的事情(在 Python 中):
def convert_to_utf8(data):
try:
data.decode('UTF-8')
return data # was already UTF-8
except UnicodeError:
return data.decode('ISO-8859-1').encode('UTF-8')
在 shell 脚本中,您可以使用iconv
它来执行转换,但您需要一种检测 UTF-8 的方法。一种方法是使用iconv
UTF-8 作为源和目标编码。如果文件是有效的 UTF-8,则输出将与输入相同。
答案4
我有点晚了,但我一直在为同样的问题苦苦挣扎……现在我找到了一个很好的方法,我忍不住要分享它:)
尽管我是 emacs 用户,但我今天还是建议您使用 vim。
使用这个简单的命令,它将重新编码你的文件,无论里面的内容是什么,都按照所需的编码进行:
vim +'set nobomb | set fenc=utf8 | x' <filename>
我从来没有发现过比这能给我带来更好结果的东西。
我希望它能够对其他人有所帮助。