最近拿到一份代码,注释是乱码,编译通不过。不得不花些时间,了解下如何查看文件的编码以及如何转换字符集。
用命令file -i filename
查看文件的字符编码(如果是Mac
,用file -I filename
),举例如下:
$ file -i readme.txt readme.txt: text/plain; charset=iso-8859-1
text/plain; charset=iso-8859-1
是一个媒体类型(也叫internet media type, mime, content-types),由type、subtype、0或多个参数组成。常见的媒体类型可以查看维基百科:list of common media types。
用echo $lang
查看终端使用的字符集:
$ echo $lang en_us.utf-8
用命令iconv
转换字符集,如将iso-8859-1
转换成utf-8
:
$ iconv -f iso-8859-1 -t utf-8 readme.txt
值得注意的是,上述命令只是输出转换后的文本,并没有直接替换文件。如果批量转换,可以写个简单脚本,转换并替换原文件,如下:
#!/usr/bin/env bash tmp_file="tmp.$$" trap "rm -f $tmp_file" exit find . -name "*.java" > $tmp_file for file in $tmp_file do #iconv -f iso-8859-1 -t utf-8 $file iconv -f gbk -t utf-8 $file -o "$file.new" mv "$file.new" $file #replace the old file done
如上例,file -i readme.txt
明明显示的是iso-8859-1
,转换成utf-8
,还是乱码。这种情况下,多半是因为原文件字符编码不是iso-8859-1
,因为这份代码来源于中国人手,就估计乱码部分应该是中文,其对应的字符编码是gbk
,再用iconv -f gbk -t utf-8 readme.txt
,果真正常。
我还遇到file -i filename
显示的字符编码是unknown-8bit
,这种情况下,只有猜了。语言对应于字符编码如下(enca
是用来检测和转换字符编码的,反正在我的例子,检测不出来):
#http://manpages.ubuntu.com/manpages/lucid/man1/enca.1.html
$sudo apt-get install enca
$ enca --list languages
belarussian: cp1251 ibm866 iso-8859-5 koi8-uni maccyr ibm855 koi8-u
bulgarian: cp1251 iso-8859-5 ibm855 maccyr ecma-113
czech: iso-8859-2 cp1250 ibm852 keybcs2 macce koi-8_cs_2 cork
estonian: iso-8859-4 cp1257 ibm775 iso-8859-13 macce baltic
croatian: cp1250 iso-8859-2 ibm852 macce cork
hungarian: iso-8859-2 cp1250 ibm852 macce cork
lithuanian: cp1257 iso-8859-4 ibm775 iso-8859-13 macce baltic
latvian: cp1257 iso-8859-4 ibm775 iso-8859-13 macce baltic
polish: iso-8859-2 cp1250 ibm852 macce iso-8859-13 iso-8859-16 baltic cork
russian: koi8-r cp1251 iso-8859-5 ibm866 maccyr
slovak: cp1250 iso-8859-2 ibm852 keybcs2 macce koi-8_cs_2 cork
slovene: iso-8859-2 cp1250 ibm852 macce cork
ukrainian: cp1251 ibm855 iso-8859-5 cp1125 koi8-u maccyr
chinese: gbk big5 hz
none: