【问题标题】:Only archive certain folders using python仅使用 python 归档某些文件夹
【发布时间】:2022-07-08 05:18:27
【问题描述】:

使用以下文件夹结构(每个元素都是一个文件夹

├─folderA
│  ├─a1
│  ├─a2
│  └─a3

有没有办法像这样将文件夹 a1 和 a2 压缩到文件夹 A.zip(包括所有文件内容和子文件夹)中:

├─folderA.zip
│  ├─a1
│  ├─a2

谢谢

【问题讨论】:

  • cd folderA; zip -r ../folderA.zip *

标签: python zip archive


【解决方案1】:

从这里稍微修改答案:Python zip multiple directories into one zip file

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(zip_dir, sub_dir_list):
    zipf = zipfile.ZipFile(zip_dir + '.zip', 'w', zipfile.ZIP_DEFLATED)
    for sub_dir in sub_dir_list:
        zipdir(sub_dir, zipf)
    zipf.close()

zip_dir = '/folderA'
sub_dir_list = ['a1', 'a2']
zipit(zip_dir, sub_dir_list)

这将创建一个包含指定子目录的/folderA.zip

【讨论】:

    【解决方案2】:

    这是一种不同的方法,它使用模式来过滤要归档的项目。

    上市:

    code00.py

    #!/usr/bin/env python
    
    import glob
    import os
    import sys
    import zipfile as zf
    
    
    def archive(src_dir, pattern="**", arc_name=None):
        items = 0
        files = 0
        if arc_name:
            if not arc_name.endswith(".zip"):
                arc_name += ".zip"
        else:
            arc_name = os.path.basename(src_dir) + ".zip"
        if pattern != "**":
            pattern = os.path.join(pattern, "**")
        with zf.ZipFile(arc_name, mode="w", compression=zf.ZIP_DEFLATED) as zipf:
            for f in glob.iglob(os.path.join(src_dir, pattern), recursive=True):
                items += 1
                if os.path.isdir(f):
                    continue
                zipf.write(os.path.normpath(f))
                files += 1
        return items, files
    
    
    def main(*argv):
        dir_name = "folderA"
        patterns = (
            "**",
            "a1*",
            "a[12]*",
        )
        for idx, pat in enumerate(patterns):
            print("Pattern {:d} (\"{:s}\"): {:d} items out of which {:d} files".format(idx, pat, *archive(dir_name, pat, dir_name + str(idx))))
    
    
    if __name__ == "__main__":
        print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
                                                       64 if sys.maxsize > 0x100000000 else 32, sys.platform))
        rc = main(*sys.argv[1:])
        print("\nDone.")
        sys.exit(rc)
    

    输出

    [cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q072900280]> sopr.bat
    ### Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ###
    
    [prompt]> tree /a /f
    Folder PATH listing for volume SSD0-WORK
    Volume serial number is AE9E-72AC
    E:.
    |   code00.py
    |
    \---FolderA
        +---a1
        |   |   f11.txt
        |   |
        |   \---a11
        |           f111.txt
        |
        +---a2
        |   \---a21
        |       \---a211
        |               f2111.tzt
        |
        \---a3
                f31.txt
    
    
    [prompt]> "e:\Work\Dev\VEnvs\py_pc064_03.09_test0\Scripts\python.exe" ./code00.py
    Python 3.9.9 (tags/v3.9.9:ccb0e6a, Nov 15 2021, 18:08:50) [MSC v.1929 64 bit (AMD64)] 064bit on win32
    
    Pattern 0 ("**"): 11 items out of which 4 files
    Pattern 1 ("a1*"): 4 items out of which 2 files
    Pattern 2 ("a[12]*"): 8 items out of which 3 files
    
    Done.
    
    [prompt]> dir /b
    code00.py
    FolderA
    folderA0.zip
    folderA1.zip
    folderA2.zip
    

    没有检查 symlinks 的处理方式,但我猜 ZipFile 取消了对它们的引用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-11
      • 2012-05-26
      • 2022-01-07
      • 2013-02-13
      • 2015-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多