【问题标题】:Python zip multiple directories into one zip filePython 将多个目录压缩成一个 zip 文件
【发布时间】:2018-02-24 01:36:44
【问题描述】:

我有一个顶级目录ds237,它下面有多个子目录:

ds237/
├── dataset_description.json
├── derivatives
├── sub-01
├── sub-02
├── sub-03
├── sub-04
├── sub-05
├── sub-06
├── sub-07
├── sub-08
├── sub-09
├── sub-10
├── sub-11
├── sub-12
├── sub-13
├── sub-21
├── sub-22
├── sub-23
├── sub-24
├── sub-25
├── sub-26
├── sub-27
├── sub-28
├── sub-29

我正在尝试根据 zip 文件的大小从 ds237 创建多个 zip 文件(具有正确的 zip 名称)。 sub01-01.zip: contain sub-01 to sub-07 sub08-13.zip : it contains sub08 to sub-13

我编写了一个创建子目录列表[sub-01,sub-02, sub-03, sub-04, sub-05] 的逻辑。我创建了列表,因此列表中所有子目录的总大小不应> 5gb。

我的问题: 是如何编写一个函数来将这些子目录(在列表中)压缩到具有正确名称的目标 zip 文件中。 基本上我想写一个函数如下:

def zipit([list of subdirs], 'path/to/zipfile/sub*-*.zip'):

我在 Linux 我通常通过以下方式实现:

'zip -r compress/sub01-08.zip ds237/sub-0[1-8]'

【问题讨论】:

    标签: python zip archive


    【解决方案1】:

    查看https://stackoverflow.com/a/1855118/375530,您可以重新使用该答案的功能将目录添加到 ZipFile。

    import os
    import zipfile
    
    
    def zipdir(path, ziph):
        # ziph is zipfile handle
        for root, dirs, files in os.walk(path):
            for file in files:
                ziph.write(os.path.join(root, file),
                           os.path.relpath(os.path.join(root, file),
                                           os.path.join(path, '..')))
    
    
    def zipit(dir_list, zip_name):
        zipf = zipfile.ZipFile(zip_name, 'w', zipfile.ZIP_DEFLATED)
        for dir in dir_list:
            zipdir(dir, zipf)
        zipf.close()
    

    zipit 函数应该使用您的预分块列表和给定名称调用。如果您想使用程序化名称(例如"path/to/zipfile/sub{}-{}.zip".format(start, end)),可以使用字符串格式。

    【讨论】:

    • 上述脚本将通过排除目录路径创建一个zip文件。假设我将/Users/aba/ds100/sub-0[1-6] 压缩到sub01-06.zip 然后当我解压缩zip 时,它应该生成以下路径ds100/sub-01 和其他目录。
    • 您还可以将relpath 更改为从path 上移两个目录。所以将os.path.join(path, '..') 更改为os.path.join(path, '..', '..'),它应该可以工作。
    • 它完成了部分工作,但是当我解压缩sub01-06.zipsub07-09.zip 时,理想情况下它应该解压缩为ds100/sub-01 ds100/sub-02 ds100/sub-03 ds100/sub-04 ds100/sub-05 ds100/sub-06 ds100/sub-07 ds100/sub-08 ds100/sub-09, However above script with chnages you suggested crates two different ds100`
    • 不确定你看到了什么,我运行了一个类似的测试并且能够提取两个 zip 以填充 ds100 目录。您的解压缩工具可能有一些配置。您也可以使用unzip zip_file.zip -d output_directory 将文件zip_file.zip 解压缩为output_directory。这也是更改代码以将ds100 放入其中的替代方法,您只需将输出目录指定为ds100
    【解决方案2】:

    您可以使用subprocess 调用“zip”并将路径作为参数传递

    【讨论】:

    • 我打算用pythonic的方式来做这个
    【解决方案3】:

    以下将为您提供带有第一个文件夹 ds100 的 zip 文件:

    import os
    import zipfile    
    
    def zipit(folders, zip_filename):
        zip_file = zipfile.ZipFile(zip_filename, 'w', zipfile.ZIP_DEFLATED)
    
        for folder in folders:
            for dirpath, dirnames, filenames in os.walk(folder):
                for filename in filenames:
                    zip_file.write(
                        os.path.join(dirpath, filename),
                        os.path.relpath(os.path.join(dirpath, filename), os.path.join(folders[0], '../..')))
    
        zip_file.close()
    
    
    folders = [
        "/Users/aba/ds100/sub-01",
        "/Users/aba/ds100/sub-02",
        "/Users/aba/ds100/sub-03",
        "/Users/aba/ds100/sub-04",
        "/Users/aba/ds100/sub-05"]
    
    zipit(folders, "/Users/aba/ds100/sub01-05.zip")
    

    例如,sub01-05.zip 的结构类似于:

    ds100
    ├── sub-01
    |   ├── 1
    |       ├── 2
    |   ├── 1
    |   ├── 2
    ├── sub-02
        ├── 1
            ├── 2
        ├── 1
        ├── 2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-03
      • 1970-01-01
      • 2014-06-12
      • 1970-01-01
      • 1970-01-01
      • 2015-09-29
      • 1970-01-01
      • 2021-04-29
      相关资源
      最近更新 更多