文件编码处理
七月 18, 2025 [tools] #encoding #iconv #convmv #vim #linux文件编码处理
查看文件编码
Vim 中查看
:set fileencoding?
enca 命令
sudo apt install enca
enca filename # 对部分 GBK 文件可能返回 "Unrecognized encoding"
file 命令
file -i filename
文件内容编码转换(iconv)
iconv -f GBK -t UTF-8 filename -o newfile
批量转换:
find . -name "*.txt" -exec iconv -f GBK -t UTF-8 {} -o {}.utf \;
enconv 也可用于转换,它是 enca 的转换工具。
文件名编码转换(convmv)
从 Windows 拷贝到 Linux 时,Windows 文件名编码为 GBK,Linux 为 UTF-8,导致文件名乱码。
sudo apt install convmv
# 测试(不实际修改)
convmv -f GBK -t UTF-8 *.txt
# 实际执行
convmv -f GBK -t UTF-8 --notest *.txt
# 递归处理
convmv -f GBK -t UTF-8 -r --notest /path/
Vim 编码设置
Vim 四个编码相关选项:
| 选项 | 含义 |
|---|---|
encoding | Vim 内部使用的编码(buffer、菜单、消息),建议 utf-8 |
fileencoding | 当前编辑文件的编码 |
fileencodings | 打开文件时自动探测编码的尝试顺序 |
termencoding | 终端编码 |
推荐 .vimrc:
set encoding=utf-8
set fileencodings=ucs-bom,utf-8,cp936,gb18030,gbk,gb2312,latin1
Vim 打开文件时:按 fileencodings 顺序探测 → 设置 fileencoding → 若与 encoding 不同则用 iconv 转换。保存时反向转换。
跨平台文件名乱码原理
"锟斤拷" 的来源
- Unicode 中无法表示的字符用
�(U+FFFD, REPLACEMENT CHARACTER)表示 - UTF-8 下
�的编码为0xEF 0xBF 0xBD - 两个连续的
�在 UTF-8 中产生:EF BF BD EF BF BD - 用 GBK 解码这 6 个字节(GBK 每汉字 2 字节):
EF BF→ 锟BD EF→ 斤BF BD→ 拷
- 得出"锟斤拷" = UTF-8 → GBK 错误解码的产物
"烫烫烫" 和 "屯屯屯"
VC Debug 模式下栈内存初始化为 0xCC(→"烫"),堆内存初始化为 0xCD(→"屯")。
正确跨平台传输文件
- 打包后再传输:在 Windows 上压缩为 zip,传至 Linux,在 Linux 上用 GBK locale 解压
- 设置 locale 为 GBK:
export LANG=zh_CN.GBK
unzip file.zip
- 用 convmv 转换文件名:
convmv -f GBK -t UTF-8 --notest *.txt
注意:如果文件已在 Linux 文件系统上被按 UTF-8 解析过一次,原始 GBK 字节可能已被替换为非法字符,此时用 convmv 也无法恢复。一定要在解压阶段就设置正确的编码环境。