简体   繁体   English

仅使用 python 归档某些文件夹

[英]Only archive certain folders using python

Using following folder structure (every element is a folder使用以下文件夹结构(每个元素都是一个文件夹

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

Is there any way to zip folders a1 and a2 into a folderA.zip (including all file contents and subfolders) like so:有没有办法将文件夹 a1 和 a2 压缩到文件夹 A.zip 中(包括所有文件内容和子文件夹),如下所示:

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

Thank you谢谢

Slightly modified answer from here: Python zip multiple directories into one zip file从这里稍微修改的答案: Python zip multiple directory into a 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)

This creates a /folderA.zip including the specified sub directories.这将创建一个包含指定子目录的/folderA.zip

Here's a different approach that uses patterns for filtering items to be archived.这是一种不同的方法,它使用模式来过滤要归档的项目。

Listing:清单:

code00.py :代码00.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)

Output :输出

 [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

Didn't check how symlinks are handled, but I guess that ZipFile dereferences them.没有检查符号链接的处理方式,但我猜ZipFile取消引用它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM