Linux下文件编码转换参考
2014-03-02 21:05:51 阿炯

在Linux中操作windows下的文件,最可能会经常遇到文件编码转换的问题,Windows中默认的文件格式是GBK(gb2312/cp396),而Linux一般都是utf8。下面将讨论在Linux中如何查看文件的编码及如何进行对文件编码进行转换的方法。

一、文件编码查看
1、使用file指令在查看文件类型时得到其编码
file test.sql
test.sql: UTF-8 Unicode text, with escape sequences

2、enca (如果你的系统中没有安装这个命令,就需要安装它)查看文件编码
$ enca filename
filename: Universal transformation format 8 bits; UTF-8
 CRLF line terminators

$ enca freeoa.txt
Simplified Chinese National Standard; GB2312
  CRLF line terminators

3、使用vim直接查看文件编码
:set fileencoding
即可显示文件编码格式。

如果你只是想查看其它编码格式的文件或者想解决用Vim查看文件乱码的问题,那么你可以在~/.vimrc 文件中添加以下内容:
set encoding=utf-8 fileencodings=ucs-bom,utf-8,cp936

这样就可以让vim自动识别文件编码(可以自动识别UTF-8或者GBK编码的文件),其实就是依照fileencodings提供的编码列表尝试,如果没有找到合适的编码,就用latin1(ASCII)编码打开。

二、文件编码转换
1、iconv 转换,操作如下:
iconv -f encoding -t encoding inputfile

比如将一个UTF-8编码的文件转换成GBK编码
iconv -f GBK -t UTF-8 file1 -o file2

把gbk编码的文件转为utf8格式
iconv -f gbk -t utf-8 tianya_1.txt -o utianya_1.txt
iconv -f GBK -t utf-8 tianya_1.txt -o utianya_1.txt
iconv -f GBK -t UTF-8 tianya_1.txt -o ut.txt

2、enconv 转换文件编码
它属于傻瓜型命令行工具,它不但能智能的识别文件的编码,而且还支持成批转换。要将一个GBK编码的文件转换成UTF-8编码,操作如下:
enconv -L zh_CN -x UTF-8 filename
enca filename.txt
enca -L zh_CN file 检查文件的编码
enca -L zh_CN -x UTF-8 file 将文件编码转换为"UTF-8"编码
enca -L zh_CN -x UTF-8 < file1 > file2 如果不想覆盖原文件可以这样

除了有检查文件编码的功能以外,”enca”还有一个好处就是如果文件本来就是你要转换的那种编码,它不会报错,还是会print出结果来,而”iconv”则会报错。

3、vi(m) 转换文件编码
在Vim中直接进行转换文件编码,比如将一个文件转换成utf-8格式
:set fileencoding=utf-8

三、文件名编码的转换
从Linux往windows拷贝文件或者从windows往Linux拷贝文件,有时会出现中文文件名乱码的情况,出现这种问题的原因是因为windows的文件名中文编码默认为GBK,而Linux中默认文件名编码为UTF8,由于编码不一致,所以导致了文件名乱码的问题。解决这个问题需要对文件名进行转码,而在Linux中专门提供了一种工具convmv进行文件名编码的转换,可以将文件名从GBK转换成UTF-8编码,或者从UTF-8转换到GBK。

另外从windows下将文件通过samba文件服务器的方式将文件复制到linux上时,可以自动地将文件名的编码转换为正确的格式,反之亦然。

1、convmv
将一个由utf8编码的文件名,转换成GBK编码,命令如下:
convmv -f UTF-8 -t GBK --notest utf8编码的文件名

这样转换以后"utf8编码的文件名"会被转换成GBK编码(只是文件名编码的转换,文件内容不会发生变化)。

四、命令参考
1、iconv
iconv [选项...] [文件...]
用于转换指定文件的编码,默认输出到标准输出设备,亦可指定输出文件。

有如下选项可用:
输入/输出格式规范:
-f, --from-code=名称 原始文本编码
-t, --to-code=名称 输出编码

信息:
-l, --list 列举所有已知的字符集

输出控制:
-c 从输出中忽略无效的字符
-o, --output=FILE 输出文件
-s, --silent 关闭警告
--verbose 打印进度信息

2、file
语法:file [-beLvz][-f <名称文件>][-m <魔法数字文件>...][文件或目录...]

补充说明:通过file指令,我们得以辨识该文件的类型。

参数:
-b  列出辨识结果时,不显示文件名称。
-c  详细显示指令执行过程,便于排错或分析程序执行的情形。
-f<名称文件>  指定名称文件,其内容有一个或多个文件名称呢感,让file依序辨识这些文件,格式为每列一个文件名称。
-L  直接显示符号连接所指向的文件的类别。
-m<魔法数字文件>  指定魔法数字文件。
-v  显示版本信息。
-z  尝试去解读压缩文件的内容。

3、convmv
convmv -f 源编码 -t 新编码 [选项] 文件名

常用参数:
-r  递归处理子文件夹
--notest  真正进行操作,请注意在默认情况下是不对文件进行真实操作的,而只是试验。
--list   显示所有支持的编码
--unescap 可以做一下转义,比如把%20变成空格


五、iconv编码转换的Perl改进工具-piconv

在使用iconv时,
iconv -f UTF-8 -t GBK --verbose mz.txt -o /tmp/11.txt

报出了下面的错误:
iconv: illegal input sequence at position 0

在文件mz.txt的开头处理,确实有一个中文符号。但在utf8环境下是不可见的,转成gbk字符后是一个'?'。使用Perl的piconv却可以成功转换
piconv -f UTF-8 -t GBK mz.txt > /tmp/11.txt

piconv是一个可执行的perl脚本,它随着模块Encode的安装而安装。它的使用方法与iconv相似。

或者自己来写一个将utf8的文本转换为gbk的代码:
use v5.20;
use Encode;

my $uf='mz.txt';

open(UF,$uf) or die 'Open file failed';

while(<UF>){
 say $_;
 Encode::_utf8_on($_);
 say encode("gbk",$_);
}       

close(UF);