【问题标题】:How to create multiple folders with names, and extract multiple zips to each different folder, with python?如何使用 python 创建多个具有名称的文件夹,并将多个 zip 提取到每个不同的文件夹?
【发布时间】:2019-06-07 17:35:17
【问题描述】:

我无法为包含不同栅格数据的多个不同 zip 文件夹创建许多不同的目录,然后在干净的脚本中将所有 zip 提取到新文件夹中。

我的代码很长而且很乱,我已经完成了我的任务。我需要有标记为 NE34_ENE35_E 等的文件夹,然后在这些目录中,我需要诸如 N34_24N34_25 等子文件夹,栅格数据将被提取到这些文件夹中。我有 100 多个 zip 文件需要提取并放在子文件夹中。

在对创建目录的方式进行了一些更改后,这是我的脚本示例。

我的文件结构是这样的:

N\\N36_E\\N36_24
N\\N36_E\\N35_25
... etc.

压缩文件名称:

n36_e024_1arc_v3_bil.zip
n36_e025_1arc_v3_bil.zip
n36_e026_1arc_v3_bil.zip
... etc.

创建目录结构的Python代码:

import os

#Create Sub directories for "NE36_"
pathname1 = "NE36_"
pathname2 = 24
directory = "D:\\Capstone\\Test\\N36_E\\" + str(pathname1) + str(pathname2)
while pathname2 < 46:
    if not os.path.exists(directory):
        os.makedirs(directory)
    pathname2 += 1
    directory = "D:\\Capstone\\Test\\N36_E\\" + str(pathname1) + str(pathname2)

#Create Sub directories for "NE37_"
pathname1 = "NE37_"
pathname2 = 24
directory = "D:\\Capstone\\Test\\N37_E\\" + str(pathname1) + str(pathname2)
while pathname2 < 46:
    if not os.path.exists(directory):
        os.makedirs(directory)
    pathname2 += 1
    directory = "D:\\Capstone\\Test\\N37_E\\" + str(pathname1) + str(pathname2)

【问题讨论】:

  • 您没有使用正确的标签,这 100% 不是 batch-file 语法。为了让熟悉该标签的观众查看您的问题,建议您查看您提出问题的方式。

标签: python directory zip extract


【解决方案1】:
import glob, os, re, zipfile

# Setup main paths.
zipfile_rootdir = r'D:\Capstone\Zipfiles'
extract_rootdir = r'D:\Capstone\Test'

# Process the zip files.
re_pattern = re.compile(r'\A([a-zA-Z])(\d+)_([a-zA-Z])0{0,2}(\d+)')

for zip_file in glob.iglob(os.path.join(zipfile_rootdir, '*.zip')):

    # Get the parts from the base zip filename using regular expressions.
    part = re.findall(re_pattern, os.path.basename(zip_file))[0]

    # Make all items in part uppercase using a list comprehension.
    part = [item.upper() for item in part]

    # Create a dict of the parts to make useful parts to be used for folder names.
    # E.g. from ['N', '36', 'E', '24']
    folder = {'outer': '{0}{1}_{2}'.format(*part),
              'inner': '{0}{2}{1}_{3}'.format(*part)}

    # Build the extraction path from each part.
    extract_path = os.path.join(extract_rootdir, folder['outer'], folder['inner'])

    # Perform the extract of all files from the zipfile.
    with zipfile.ZipFile(zip_file, 'r') as zip:
        zip.extractall(extract_path)

2个主要设置值,即:

  1. zipfile_rootdir 是 zip 文件所在的位置。
  2. extract_rootdir 是提取到的位置。

字符串前的r 被视为原始字符串, 所以不需要反斜杠转义。

一个正则表达式被编译并用于提取 用于 zip 文件名的文本 提取路径。

来自压缩文件:

n36_e024_1arc_v3_bil.zip

使用正则表达式提取部分序列:

n, 36, e, 24

每个项目都是大写的,用于创建字典 命名为 folders 包含键和值:

'outer': 'N36_E'
'inner': 'NE36_24'

extract_path 将通过加入来存储完整路径 extract_rootdirfolder['outer']folder['inner']

最后,通过with 使用上下文管理器,将提取 zip 文件。


正则表达式:

re_pattern = re.compile(r'\A([a-zA-Z])(\d+)_([a-zA-Z])0{0,2}(\d+)')

之前的正则表达式模式的编译 循环是为了避免模式的多次编译 在循环。 在字符串前使用r是为了通知Python 那个字符串应该被解释为原始的 即没有反斜杠转义。 原始字符串对于正则表达式很有用,因为 反斜杠转义用于模式。

正则表达式模式:

\A([a-zA-Z])(\d+)_([a-zA-Z])0{0,2}(\d+)

正则表达式要处理的字符串:

n36_e024_1arc_v3_bil.zip
  1. \A 仅匹配字符串的开头。 这是一个锚点,不匹配任何字符。
  2. ([a-zA-Z]) 匹配任何字母字符。 [] 匹配其中的任何字符。 azAZ 匹配。 n 将被匹配。 封闭的() 是该组捕获到的存储 返回的序列。所以现在的序列是n,
  3. (\d+) 匹配 1 位或更多位。 \d 是任意数字 + 告诉它继续匹配更多。 序列变为n, 36,
  4. _ 是文字,因为 () 没有包含它,所以它 匹配但未添加到序列中。
  5. ([a-zA-Z]) 同第 2 点。 序列变为n, 36, e,
  6. 0{0,2} 匹配一个零 0,零到 2 次 {0,2}。 没有(),所以没有添加到序列中。
  7. (\d+) 同第 3 点。 序列变为n, 36, e, 24
  8. 字符串的其余部分被忽略为模式 已经到了尽头。这就是为什么\A 是 使用所以模式不能从任何地方开始,并且 继续到不需要的字符串的末尾。

格式:

大写后的序列为N, 36, E, 24 通过列表理解。

  1. 模式{0}{1}_{2} 订购0, 1, 2, 所以0是N,1是36,2是E成为 N36_E_ 是模式中的文字。
  2. 模式{0}{2}{1}_{3}已排序 0, 2, 1, 3。 0 是N,2 是E,1 是36 3 是 24 变成 NE36_24

参考资料:

  • Python 2:

  • Python 3:

    • re 用于正则表达式的模块。
    • format 格式化字符串的方法。
    • list comprehensions 用于将序列中的项目大写。
    • zipfile 用于处理 zip 档案的模块。

【讨论】:

  • 嗨,迈克尔,感谢您的帮助!我想知道你是否可以帮助我更多,我实际上改变了一些东西,但我已经创建了文件结构!有没有办法创建一个脚本来读取 n34_e025_1arc_v3_bil.zip 的数量并将其解压缩到给定的文件夹中?
  • 我的答案不是一个完整的脚本的原因是因为我没有实现它的所有信息。您的评论仍然未知,因为您更改了结构 并希望提取到给定文件夹。我需要理解这意味着什么,即 given 太宽泛了。如果您可以将详细信息基于少量文件,并且可能使用提示符中的tree 命令(例如每个目录中的tree /a /f)来显示结构并粘贴以更新问题。如果我可以复制所需的结构,我可能会制作一个完整的脚本并进行测试,以完成所需的工作。
  • 抱歉我还在学习,我会根据我所做的更改和更多信息进行编辑!
  • 根据最新的目录结构更新了答案。尝试一下,看看我在文本提取、部件顺序等方面是否正确。
  • 刚刚更新了代码中的旧注释以避免混淆。请注意,zip 提取将创建目录结构,因此不需要创建目录的代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-08
  • 2011-12-27
  • 2021-04-02
  • 1970-01-01
相关资源
最近更新 更多