zip 與 unzip 是 Linux 與 Windows 交換檔案的標準格式,支援加密、分卷、增量更新等實用功能。本文詳細說明常用操作與進階技巧。
# 壓縮單一檔案
zip archive.zip file.txt
# 遞迴壓縮整個目錄(含子目錄)
zip -r archive.zip /path/to/dir/
# 壓縮多個檔案/目錄
zip -r archive.zip dir1/ dir2/ file1.txt file2.log
# 排除特定檔案/模式
zip -r archive.zip /path/to/dir -x "*.log" "*.tmp" "node_modules/*"
# 不包含目錄結構(僅檔案)
zip -j archive.zip /path/to/dir/*
# 解壓到當前目錄
unzip archive.zip
# 解壓到指定目錄
unzip -d /target/path archive.zip
# 不提示直接覆蓋
unzip -o archive.zip
# 僅列出內容不解壓
unzip -l archive.zip
# 測試壓縮檔完整性
unzip -t archive.zip
# 解壓單一檔案
unzip archive.zip "path/to/file.txt" -d /target/
# 解壓時轉換編碼(解決中文檔名亂碼)
unzip -O CP950 archive.zip # 繁體中文舊檔
unzip -O UTF-8 archive.zip # 現代 UTF-8 編碼
# 互動式設定密碼(較安全,不留歷史)
zip -e secret.zip sensitive.txt
# 指定密碼(不建議,會留在 history)
zip -P 'password123' secret.zip sensitive.txt
# 使用 AES-256 加密(需 zip 3.0+)
zip -e --encryption-method aes-256 secret.zip sensitive.txt
⚠️ 注意:標準 ZipCrypto 加密強度低,敏感資料建議改用 7z -p -mhe=on(AES-256 + 標頭加密)或 gpg。
# 更新壓縮包(新增/覆蓋較新檔案)
zip -u archive.zip updated_file.txt
# 刪除壓縮包內檔案
zip -d archive.zip "obsolete/*.log"
# 移動檔案進壓縮包(刪除原檔)
zip -m archive.zip new_file.txt
# 整理壓縮包(移除已刪除檔案的殘留資料)
zip -F archive.zip --out archive_fixed.zip
# 修復損壞的壓縮包
zip -FF broken.zip --out fixed.zip
# 分割成 100MB 一卷
zip -s 100m -r large_archive.zip /big/data/
# 產生:large_archive.zip, large_archive.z01, large_archive.z02...
# 合併還原(需先合併再解壓)
zip -s 0 large_archive.zip --out merged.zip
unzip merged.zip
# 壓縮等級 0-9(0=不壓縮/最快,9=最高壓縮/最慢)
zip -9 -r best.zip /data/
zip -1 -r fast.zip /data/
# 並行壓縮(需 pigz 支援,zip 3.0+)
# zip 本身不支援多執行緒,大量檔案建議改用 tar + pigz
| 問題 | 解決方案 |
|---|---|
| 中文檔名亂碼 | 解壓時指定 -O CP950 或 -O UTF-8;壓縮時建議在 UTF-8 環境建立 |
| Argument list too long | 檔案過多,改用 find . -name "*.txt" -print0 | zip -0 archive.zip -@ |
| 權限不保留 | zip 不保留擁有者/群組,需搭配 tar 或使用 7z |
| 大於 4GB 檔案 | 需 Zip64 支援(現代 zip 預設支援),確認 unzip 版本 ≥ 6.0 |
#!/bin/bash
DATE=$(date +%F_%H-%M)
SRC="/var/www/html"
DEST="/backup/web_${DATE}.zip"
LOG="/var/log/backup.log"
zip -r -9 -q "$DEST" "$SRC" -x "*/cache/*" "*/logs/*" "*.tmp" 2>>"$LOG"
if [ $? -eq 0 ]; then
echo "[$(date)] Backup success: $DEST" >> "$LOG"
# 保留最近 7 份
find /backup -name "web_*.zip" -mtime +7 -delete
else
echo "[$(date)] Backup FAILED" >> "$LOG"
fi