颜林林的个人网站

如何解决Linux下解压缩zip文件出现乱码的问题

2019-12-11 21:16

自从多年前放弃Windows,完全改用Linux作为日常工作环境后,遇到的其中一个麻烦,就是解压缩来自Windows系统的zip压缩包,一旦涉及文件名或目录名有中文,其解压缩结果就总是乱码。之前尝试过各种环境变量配置方法和第三方工具,但都没法很好地解决,于是只好请同事朋友改用rar格式压缩,或者干脆弄个Windows虚拟机,回到Windows系统中解压缩。

最近通过一系列调研和尝试,终于找到了合适的解决方法,大致需要考虑两个方面:

  1. 在运行unzip命令时,需要指定字符集为zh_CN.GBK,且同时带上-UU参数,以确保unzip结果不会根据缺省字符集utf8进行转码;
  2. 然后,需要遍历解压缩的整个目录树,使用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压缩包,处理起来就很方便了。