[英]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:清单:
[Python.Docs]: zipfile - Work with ZIP archives [Python.Docs]: zipfile - 使用 ZIP 档案
[Python.Docs]: glob - Unix style pathname pattern expansion [Python.Docs]:glob - Unix 风格的路径名模式扩展
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.