自从多年前放弃Windows,完全改用Linux作为日常工作环境后,遇到的其中一个麻烦,就是解压缩来自Windows系统的zip压缩包,一旦涉及文件名或目录名有中文,其解压缩结果就总是乱码。之前尝试过各种环境变量配置方法和第三方工具,但都没法很好地解决,于是只好请同事朋友改用rar格式压缩,或者干脆弄个Windows虚拟机,回到Windows系统中解压缩。
最近通过一系列调研和尝试,终于找到了合适的解决方法,大致需要考虑两个方面:
- 在运行
unzip
命令时,需要指定字符集为zh_CN.GBK
,且同时带上-UU
参数,以确保unzip结果不会根据缺省字符集utf8
进行转码;
- 然后,需要遍历解压缩的整个目录树,使用
convmv -f gbk -t utf8
命令进行改名,将字符集从gbk
转换到utf8
。
在使用convmv
改名前,应先对其中各目录设置可写权限,否则该目录下的文件改名会因权限问题而失败。
整个过程,我写了一个简单的小脚本unzipw.sh
,内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
#!/bin/bash
if [ -z "$1" ]; then
echo "Extract .zip file from Windows."
echo "Usage: $(basename $0) <xx.zip>"
exit 1
fi
DIRNAME="$(basename "$1" .zip)"
if [ -d "${DIRNAME}" ]; then
DIRNAME="$(mktemp -d "${DIRNAME}-XXXX")"
fi
mkdir -pv "${DIRNAME}"
set -e
# extract files
LANG=zh_CN.GBK unzip -UU "$1" -d "${DIRNAME}"
# allow to modify directory
find "${DIRNAME}" -type d -exec chmod u+w "{}" \;
# correct encoding
convmv -f gbk -t utf8 --notest -r "${DIRNAME}"
# move single subdir out
if [ "$(ls "${DIRNAME}")" == "${DIRNAME}" ]; then
mv "${DIRNAME}/${DIRNAME}"/* "${DIRNAME}/"
rmdir "${DIRNAME}/${DIRNAME}"
fi
|
从此,对来自Windows系统的zip压缩包,处理起来就很方便了。