多个 ZIP 包合并成一个 ZIP:图形界面、命令行、Python 全方案

15次阅读
没有评论

日常开发、数据导出、批量下载经常遇到一堆独立.zip文件,需要把它们合成一个压缩包。这里区分两种场景:

  1. 把多个独立 zip 作为内部文件打包进新 zip:新 zip 里面包含若干个 zip 子文件
  2. 把各个 zip 内部的文件全部提取出来,合并到同一个新 zip(业务最常用)

⚠️注意:本文处理多个独立普通 zip,不是.zip.001/.z01这种分卷压缩包,分卷是另外一套逻辑。

场景一:直接把多个 zip 文件打包进新 zip

简单理解:新 zip 里面存放的是原来的.zip文件本身,不解开内部内容。

Windows 图形界面

  1. 选中所有需要合并的a.zipb.zipc.zip
  2. 右键 → 发送到 → 压缩 (zipped) 文件夹
  3. 直接生成新 zip,内部就是原来那几个 zip 文件。

缺点:Windows 自带 zip 不支持密码、不支持高级压缩;追求功能推荐 7‑Zip(免费开源)。

Linux /macOS 命令行

bash

# 将a.zip b.zip c.zip打包为all_in_one.zip,内部保留原zip文件
zip all_in_one.zip a.zip b.zip c.zip

Python 实现

python

运行

import zipfile

zip_list = ["a.zip", "b.zip", "c.zip"]
out_zip = "all_in_one.zip"

with zipfile.ZipFile(out_zip, "w", zipfile.ZIP_DEFLATED) as zf:
    for fp in zip_list:
        zf.write(fp)  # 直接把zip文件作为条目写入
print(f"生成完成:{out_zip}")

场景二:合并各个 zip 内部的文件(最常用)

需求:有part1.zippart2.zip,每个 zip 里面有一堆文档图片,希望输出一个新 zip,里面是所有解压出来的文件,不再包含子 zip 包。

传统笨办法:全部解压到临时文件夹,再重新压缩。缺点:占用大量磁盘临时空间,大文件很慢。下面提供命令行、Python 两种方案。

方案 A:7‑Zip 命令行(Windows 推荐)

需要先安装 7‑Zip,把7z.exe加到环境变量或者写全路径。

思路:管道流式处理,不落地大量临时文件,读取每个 zip 内部条目,直接写入新归档。

cmd

:: Windows cmd示例,把part1.zip part2.zip内全部文件合并输出merged.zip
(for %%z in (part1.zip part2.zip) do 7z x -so "%%z") | 7z a -si merged.zip

提示:PowerShell 语法略有区别,适合写 bat 脚本批量自动化。

方案 B:Linux/macOS Shell

bash

# 方式1:临时目录中转,简单稳妥
mkdir tmp
for z in part1.zip part2.zip; do unzip -q "$z" -d tmp; done
zip -r merged.zip tmp/*
rm -rf tmp

方案 C:Python 脚本(跨平台,开发自动化首选)

不解压到磁盘,内存读取每个 zip 内部条目,写入新 zip,保留目录结构,适合程序批量处理。

python

运行

import zipfile
from pathlib import Path

def merge_inner_files(output_zip: str, input_zip_paths: list[str]):
    """
    将多个zip内部的所有文件合并到同一个输出zip
    :param output_zip: 输出zip路径
    :param input_zip_paths: 待合并zip文件列表
    """
    with zipfile.ZipFile(output_zip, "w", zipfile.ZIP_DEFLATED) as out_zf:
        for zip_path in input_zip_paths:
            with zipfile.ZipFile(zip_path, "r") as in_zf:
                for info in in_zf.infolist():
                    # 跳过目录条目,只处理文件
                    if info.is_dir():
                        continue
                    # 读取源zip内部文件字节流,直接写入目标zip
                    with in_zf.open(info) as f:
                        out_zf.writestr(info, f.read())
    print(f"✅合并完成,输出文件:{output_zip}")

if __name__ == "__main__":
    files = ["part1.zip", "part2.zip", "part3.zip"]
    merge_inner_files("merged_all.zip", files)

注意:如果多个 zip 内部存在同名文件,后面的会覆盖前面的,业务使用时建议增加重名冲突检测逻辑。

容易踩坑:分卷 zip 与普通 zip 不要搞混

很多人混淆两个概念:

  1. 多个独立 zip 文件a.zipb.zip,各自独立,上面的方法处理。
  2. zip 分卷文件data.zip.001data.zip.002,是同一个大文件拆分出来的碎片,不是独立压缩包。

分卷合并命令(Linux):

bash

cat data.zip.* > full_data.zip

Windows cmd:

cmd

copy /B data.zip.001 + data.zip.002 full_data.zip

分卷直接用 7‑Zip 打开第一个分卷文件解压即可,软件会自动识别全部片段,不需要手动二进制拼接。

各方案优缺点对比

表格

方案 优点 缺点 适用场景
Windows 右键发送到压缩包 零安装,操作简单 无密码、压缩率一般 少量文件快速打包
7‑Zip 命令行 流式处理,少占磁盘,支持加密 需要安装 7‑Zip Windows 批量脚本、大压缩包
Shell 脚本 (unzip+zip) Linux/macOS 原生,简单直观 会产生临时目录 服务器、CI 脚本
Python zipfile 跨平台,可嵌入业务代码,精细控制逻辑 需要处理重名覆盖问题 后端程序、自动化流水线

常见问题 FAQ

Q:合并后 zip 打开报错损坏?

  1. 区分你是要 “打包 zip 本身” 还是 “合并 zip 内部文件”,两种逻辑代码不能混用。
  2. Python 版本注意:加密的 zip,标准库zipfile不支持读取加密 zip 内部内容,遇到带密码压缩包,建议改用 7‑zip 命令行。

Q:文件特别大,内存 OOM 怎么办?

上面 Python 示例一次性f.read()把文件读进内存;超大文件建议改用分块流式读写,或者退回到 “解压临时目录再压缩” 方案。

Q:保留原始目录结构吗?

示例代码会保留 zip 内部原有的目录路径;如果想要全部摊平到根目录,修改writestr第二个参数,重写 arcname。

正文完
可以使用微信扫码关注公众号(ID:xzluomor)
post-qrcode
 0
评论(没有评论)
验证码