文件编码处理

七月 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 四个编码相关选项:

选项含义
encodingVim 内部使用的编码(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 转换。保存时反向转换。

跨平台文件名乱码原理

"锟斤拷" 的来源

  1. Unicode 中无法表示的字符用 (U+FFFD, REPLACEMENT CHARACTER)表示
  2. UTF-8 下 的编码为 0xEF 0xBF 0xBD
  3. 两个连续的 在 UTF-8 中产生:EF BF BD EF BF BD
  4. 用 GBK 解码这 6 个字节(GBK 每汉字 2 字节):
    • EF BF → 锟
    • BD EF → 斤
    • BF BD → 拷
  5. 得出"锟斤拷" = UTF-8 → GBK 错误解码的产物

"烫烫烫" 和 "屯屯屯"

VC Debug 模式下栈内存初始化为 0xCC(→"烫"),堆内存初始化为 0xCD(→"屯")。

正确跨平台传输文件

  1. 打包后再传输:在 Windows 上压缩为 zip,传至 Linux,在 Linux 上用 GBK locale 解压
  2. 设置 locale 为 GBK
export LANG=zh_CN.GBK
unzip file.zip
  1. 用 convmv 转换文件名
convmv -f GBK -t UTF-8 --notest *.txt

注意:如果文件已在 Linux 文件系统上被按 UTF-8 解析过一次,原始 GBK 字节可能已被替换为非法字符,此时用 convmv 也无法恢复。一定要在解压阶段就设置正确的编码环境。