ZIP 格式早期無編碼標準,Windows 風格 ZIP 多用 GBK/CP936 編碼檔名,Linux 預設 UTF-8 解碼,導致中文檔名變亂碼或解壓失敗。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# uzip.py
import os, sys, zipfile
zip_path = sys.argv[1]
print(f"Processing: {zip_path}")
with zipfile.ZipFile(zip_path, 'r') as zf:
for name in zf.namelist():
try:
# 嘗試 GBK 解碼(中文 Windows 主流)
utf8_name = name.encode('cp437').decode('gbk')
except UnicodeDecodeError:
# 回退 UTF-8
utf8_name = name
print(f"Extracting: {utf8_name}")
dir_name = os.path.dirname(utf8_name)
if dir_name and not os.path.exists(dir_name):
os.makedirs(dir_name, exist_ok=True)
data = zf.read(name)
if not os.path.exists(utf8_name):
with open(utf8_name, 'wb') as f:
f.write(data)
print("Done.")
使用:chmod +x uzip.py && ./uzip.py xxx.zip
優點:跨平台、自動建立目錄、可擴展支援更多編碼。缺點:需 Python 環境。
-O 指定編碼(最快、原生)unzip -O CP936 xxx.zip # GBK/GB18030 別名
# 或
unzip -O GBK xxx.zip
注意:man unzip 未記錄 -O 參數,但 unzip --help 顯示 -O CHARSET。部分舊版 unzip 不支援,需更新套件。
# /etc/environment 或 ~/.bashrc
export UNZIP="-O CP936"
export ZIPINFO="-O CP936"
重新登入後,所有 unzip、zipinfo 自動使用 CP936 解碼。
jar xvf xxx.zip
JDK 自帶 jar 工具內建處理 ZIP 編碼,通常能正確還原中文檔名,無額外參數。
| 方法 | 適用場景 | 優點 | 缺點 |
|---|---|---|---|
| Python 腳本 | 批次處理、編碼不確定、需自定邏輯 | 彈性最高、可遞迴修正 | 需 Python、速度較慢 |
| unzip -O | 單檔快速解壓、確知編碼 | 原生、無依賴、速度快 | 舊版不支援、參數未文檔化 |
| 環境變數 | 長期使用、團隊統一標準 | 一次設定、全域生效 | 影響所有 unzip 行為、可能誤傷 UTF-8 ZIP |
| jar xvf | 已安裝 JDK、臨時救援 | 跨平台、免配置 | 需 JDK、非標準解壓工具 |
# 使用 file 指令查看(僅供參考)
file xxx.zip
# Python 快速探測
python3 -c "
import zipfile, sys
zf = zipfile.ZipFile(sys.argv[1])
for n in zf.namelist()[:5]:
try:
print(n.encode('cp437').decode('gbk'))
except:
print(n.encode('cp437').decode('utf-8', 'replace'))
" xxx.zip
UNZIP="-O CP936"unzip -O GBK 或 jar xvfzip -r -utf8(Info-ZIP 3.1+)生成 UTF-8 編碼 ZIP,源頭消除亂碼