【问题标题】:Python - Creating several zip files from several folders in one directory depending on the folders' filename pattern [duplicate]Python - 根据文件夹的文件名模式从一个目录中的多个文件夹创建多个 zip 文件
【发布时间】:2021-04-02 04:15:16
【问题描述】:

我希望标题不要太混乱。请看下面的图片和gif。

假设我有一个这样的目录。现在我想压缩所有匹配“cs-”、“es-”、“fr-”等的文件夹,如下图所示:

编辑:所有文件夹都有多个子文件夹和/或文件。

到目前为止,我设法找到了我想要的所有文件夹:

import zipfile, os, shutil, pprint

from pathlib import Path


userPath1 = Path(input("Please give me a path:",))

# '- set(userPath1.glob("*.*")' is deducted so that only folders (and no files) are stored in the variables
csFileServerFileList = list(set(userPath1.glob('cs-*')) - set(userPath1.glob("*.*")))
esFileServerFileList = list(set(userPath1.glob('es-*')) - set(userPath1.glob("*.*")))
frFileServerFileList = list(set(userPath1.glob('fr-*')) - set(userPath1.glob("*.*")))
itFileServerFileList = list(set(userPath1.glob('it-*')) - set(userPath1.glob("*.*")))
jaFileServerFileList = list(set(userPath1.glob('ja-*')) - set(userPath1.glob("*.*")))
nlFileServerFileList = list(set(userPath1.glob('nl-*')) - set(userPath1.glob("*.*")))
plFileServerFileList = list(set(userPath1.glob('pl-*')) - set(userPath1.glob("*.*")))
ptFileServerFileList = list(set(userPath1.glob('pt-*')) - set(userPath1.glob("*.*")))
ruFileServerFileList = list(set(userPath1.glob('ru-*')) - set(userPath1.glob("*.*")))
trFileServerFileList = list(set(userPath1.glob('tr-*')) - set(userPath1.glob("*.*")))

langFileServerList = [
                        csFileServerFileList, esFileServerFileList, frFileServerFileList, itFileServerFileList,
                        jaFileServerFileList, nlFileServerFileList, plFileServerFileList, ptFileServerFileList,
                        ruFileServerFileList, trFileServerFileList
                        ]

for list in langFileServerList:
    for i in list:
        print(i)

我知道这种方法:

>>> newZip = zipfile.ZipFile('new.zip', 'w')
>>> newZip.write('spam.txt', compress_type=zipfile.ZIP_DEFLATED)
>>> newZip.close()

但它只适用于文件而不适用于文件夹。

非常感谢您的帮助!

【问题讨论】:

标签: python


【解决方案1】:

通过修改similar question,我们可以轻松地将目录添加到 zip 文件中:

#!/usr/bin/env python
import os
import zipfile

def create_zip(zip_name: str, paths: list):
    # zipf is zipfile handle
    zipf = zipfile.ZipFile(zip_name, 'w', zipfile.ZIP_DEFLATED)
    # Add each file from each path
    for path in paths:
        for root, dirs, files in os.walk(path):
            for file in files:
                zipf.write(os.path.join(root, file))
    zipf.close()


if __name__ == '__main__':
    # Create a zip with both the tmp/ and tmp2/ folders called myZip.zip
    create_zip('myZip.zip', ['tmp/', 'tmp2/'])

因此,使用您想要压缩的文件夹列表,您将能够做到:

# We need the names of our zip files somehow, here's one way
zip_names = ['cd.zip', 'es.zip', 'fr.zip', ...]

for zip_name, paths in zip(zip_names, langFileServerList):
    create_zip(zip_name, paths)

编辑(完整工作示例):

#!/usr/bin/env python
import os
import zipfile

def create_zip(zip_name: str, paths: list):
    # zipf is zipfile handle
    zipf = zipfile.ZipFile(zip_name, 'w', zipfile.ZIP_DEFLATED)
    # Add each file from each path
    for path in paths:
        for root, dirs, files in os.walk(path):
            for file in files:
                zipf.write(os.path.join(root, file))
    zipf.close()


def get_dir_list():
    # Get list of all relativ directories
    dirs = [name for name in os.listdir(".") if os.path.isdir(name)]
    # Sort by prefix
    sorted_dirs = {}
    for directory in dirs:
        # We can user the prefix as a key to croup directories together
        prefix = directory.split('-')[0]
        # Check if the key already exists in the sorted dictionary
        if prefix in sorted_dirs.keys():
            # Append the directory to the existing list
            sorted_dirs[prefix].append(directory)
        else:
            # Create the key with a list containing the directory
            sorted_dirs[prefix] = [directory]
    # Returning sorted_dirs.items() will return a list of key value pairs
    return sorted_dirs.items()



if __name__ == '__main__':
    dirs = get_dir_list()
    print(dirs)
    for lang, lang_dirs in dirs:
        create_zip(lang + ".zip", lang_dirs)

【讨论】:

  • 嘿,谢谢!您提供的解决方案会压缩从“用户”开始的所有内容,但我只需从文件所在的位置压缩就可以了。我检查了您发布的“类似问题”,并且想知道另一位用户的评论:stackoverflow.com/questions/1855095/…。我也尝试使用zipf.write(os.path.relpath(os.path.join(root, file), os.path.join(path, '..'))),但它不起作用(FileNotFoundError:WinError 3)。我有点不知所措。
  • 这可能是因为路径列表需要是字符串形式的相对路径列表
  • 我也想知道:这部分有必要吗? if __name__ == '__main__': # Create a zip with both the tmp/ and tmp2/ folders called myZip.zip create_zip('myZip.zip', ['tmp/', 'tmp2/'])
  • 那部分只是演示如何使用上面定义的create_zip 函数。所以不,你不需要它
  • 谢谢! “这可能是因为路径列表需要是作为字符串的相对路径列表”->也许是因为我正在尝试做的事情超出了我目前的技能水平——但我能问一下我会怎么做吗?
猜你喜欢
  • 2019-11-07
  • 1970-01-01
  • 1970-01-01
  • 2020-11-18
  • 2013-10-24
  • 2021-04-21
  • 2011-12-27
  • 2018-08-09
相关资源
最近更新 更多