Linux下用iconv转换中文编码需指定正确源编码,优先试GBK,再试GB18030,避免误用GB2312;遇“Illegal input sequence”应检查编码判断或混码,可用enca识别;批量转换须用临时文件+mv确保安全;终端乱码需核对locale设置,且UTF-8文件通常无需BOM。

直接用 iconv 转换,但必须指定正确源编码
Linux 下最可靠的方式就是 iconv,但它不会自动猜编码——你得明确告诉它原始文件是 GBK 还是 GB2312 或 GB18030。三者不等价:GBK 是 GB2312 的超集,GB18030 又是 GBK 的超集。如果乱试,比如用 GB2312 去转实际是 GBK 的文件,会遇到“非法字符序列”错误或部分汉字变乱码。
实操建议:
- 优先尝试
GBK:多数 Windows 生成的中文文本(尤其是近年)实际是GBK编码 - 若失败,再试
GB18030:它向后兼容GBK,对生僻字支持更好 - 避免只写
GB2312:它不包含“镕”“堃”等扩展汉字,强行使用会导致截断或报错 - 命令示例:
iconv -f GBK -t UTF-8 input.txt -o output.txt
iconv 报 “Illegal input sequence” 怎么办
这个错误说明 iconv 在输入流中遇到了它无法按指定编码解析的字节组合。常见原因不是文件本身损坏,而是源编码判断错了,或者文件混用了多种编码(比如部分行是 UTF-8、部分是 GBK)。
解决路径:
- 先用
file -i input.txt看系统粗略判断(但不准,仅作参考) - 更准一点用
enca -L zh input.txt(需安装enca),它专为中文编码识别优化 - 实在不确定,可逐个试:
iconv -f GBK -t UTF-8 //IGNORE input.txt(加//IGNORE跳过坏字节) - 慎用
//TRANSLIT:它会把无法映射的字符替换成近似 ASCII 字符(如“你好”→“ni hao”),适合日志类场景,但会破坏原文
批量转换多个文件,别用重定向覆盖原文件
想把当前目录下所有 .txt 文件从 GBK 转成 UTF-8,并保留原名?别直接写 > input.txt,那会清空原文件再写入,一旦出错就丢数据。
安全做法是用临时文件 + mv 替换:
for file in *.txt; do
iconv -f GBK -t UTF-8 "$file" > "${file%.txt}_utf8.txt" && mv "${file%.txt}_utf8.txt" "$file"
done
要点:
- 用
${file%.txt}去掉后缀,避免硬编码拼接出错 -
&&保证只有转换成功才执行mv,失败时原文件完好 - 大文件慎用管道:
cat *.txt | iconv会把所有内容拼一起,失去单文件边界 - 如需递归处理子目录,改用
find . -name "*.txt" -exec iconv -f GBK -t UTF-8 {} -o {}.utf8 \;
转换后仍是乱码?检查终端和编辑器是否真用了 UTF-8
即使 iconv 转换完全正确,你在终端里 cat output.txt 还看到乱码,大概率是终端本身没设对编码。Linux 终端(如 GNOME Terminal、xterm)默认依赖系统 locale,不是文件编码。
验证与修复:
- 运行
locale | grep UTF,确认LANG或LC_CTYPE是类似zh_CN.UTF-8的值 - 如果不是,临时生效:
export LANG=zh_CN.UTF-8;永久修改需改/etc/default/locale或用户 shell 配置 - Vim 用户注意:
:set encoding=utf-8控制 Vim 内部编码,但打开文件时还需:e ++enc=gbk手动指定读取编码 - Sublime Text / VS Code 通常自动探测,但右下角编码显示如果是 “GBK”,点它手动选 “Reopen with Encoding → UTF-8”
真正容易被忽略的是:iconv 只管字节转换,不管 BOM。UTF-8 文件加 BOM(EF BB BF)在 Linux 工具链里反而是累赘,多数脚本、编译器、Git 都不期望它。所以除非明确对接 Windows-only 工具,否则转换后别加 BOM —— iconv 默认也不加。


















