разархивировать несколько CSV-файлов из разных мест назначения в один общий пункт назначения - PullRequest
0 голосов
/ 03 февраля 2019

В настоящее время я использую некоторый код, который загружает данные CSV в zip-файлы для каждого месяца каждого года, файлы загружаются и затем сохраняются следующим образом:

folders

В настоящее время эти папки находятся только на моем рабочем столе.

После того, как я нажму, скажем, папку 2011, вы сможете увидеть папку для каждого месяца, jan, feb и т. Д.До сих пор я пробовал это:

import os, zipfile

z = zipfile.ZipFile('PUBLIC_*.zip')
for f in z.namelist():
    if f.endswith('/'):
        os.makedirs(f)

но, похоже, это не работает?

Любая помощь будет оценена.

Ответы [ 2 ]

0 голосов
/ 04 февраля 2019

Похоже, что это больше связано с обходом файловой системы, чем zipfile .Для этого вы можете использовать [Python 3]: glob - расширение шаблона имени в стиле Unix , а для обработки .zip обработка файлов использовать [Python 3]: zipfile - Workс архивами ZIP .

Для получения более подробной информации о обходе каталогов, проверьте [SO]: Как мне вывести список всех файлов каталога?(@ Ответ КристиФати) .

code.py :

#!/usr/bin/env python3

import sys
import os
import glob
import zipfile


INPUT_DIR = ".\\InDir"
OUTPUT_DIR = ".\\OutDir"


def get_zip_files(path, start_pattern):  # Python 3.5 + !!!
    return glob.iglob(os.path.join(INPUT_DIR, os.path.join("**", start_pattern + "*.zip")), recursive=True)


def main():
    for item in get_zip_files(INPUT_DIR, "PUBLIC_"):
        print("Found .zip file that matches pattern: {:s}".format(item))
        zf = zipfile.ZipFile(item)
        for name in zf.namelist():
            if name.lower().endswith(".csv"):
                print("    Extracting {:s}".format(name))
                zf.extract(name, path=OUTPUT_DIR)


if __name__ == "__main__":
    print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
    main()

Примечания :

  • Я создал (в моем cwd ) древовидную структуру, которая проще, чем ваша, но принцип тот же
  • Используются файлы-пустышки
  • Алгоритм прост:
    • Поиск входного каталога для .zip файлов, которые соответствуют желаемому шаблону (имя начинается с PUBLIC_ )
    • Для каждого такого файла извлеките все .csv файлов, которые он содержит в выходном каталоге dir

Вывод :

e:\Work\Dev\StackOverflow\q054498244>dir /b
code.py
InDir
OutDir

e:\Work\Dev\StackOverflow\q054498244>dir /b /s InDir
e:\Work\Dev\StackOverflow\q054498244\InDir\Dir0
e:\Work\Dev\StackOverflow\q054498244\InDir\Dir0\Dir00
e:\Work\Dev\StackOverflow\q054498244\InDir\Dir0\Dir01
e:\Work\Dev\StackOverflow\q054498244\InDir\Dir0\Dir00\OTHER_FILE.zip
e:\Work\Dev\StackOverflow\q054498244\InDir\Dir0\Dir00\PUBLIC_DVD_DISPATCH_UNIT_SCDATA_00.zip
e:\Work\Dev\StackOverflow\q054498244\InDir\Dir0\Dir01\PUBLIC_DVD_DISPATCH_UNIT_SCDATA_01.zip

e:\Work\Dev\StackOverflow\q054498244>dir /b OutDir

e:\Work\Dev\StackOverflow\q054498244>"e:\Work\Dev\VEnvs\py_064_03.06.08_test0\Scripts\python.exe" code.py
Python 3.6.8 (tags/v3.6.8:3c6b436a57, Dec 24 2018, 00:16:47) [MSC v.1916 64 bit (AMD64)] on win32

Found .zip file that matches pattern: .\InDir\Dir0\Dir00\PUBLIC_DVD_DISPATCH_UNIT_SCDATA_00.zip
    Extracting PUBLIC_DVD_DISPATCH_UNIT_SCDATA_0.csv
Found .zip file that matches pattern: .\InDir\Dir0\Dir01\PUBLIC_DVD_DISPATCH_UNIT_SCDATA_01.zip
    Extracting PUBLIC_DVD_DISPATCH_UNIT_SCDATA_1.csv

e:\Work\Dev\StackOverflow\q054498244>dir /b OutDir
PUBLIC_DVD_DISPATCH_UNIT_SCDATA_0.csv
PUBLIC_DVD_DISPATCH_UNIT_SCDATA_1.csv

@ EDIT0 :

Для Python 2 совместимость, просто замените get_zip_files с версией ниже:

def get_zip_files(path, start_pattern):
    start_pattern_lower = start_pattern.lower()
    entries = os.listdir(path)
    for entry in entries:
        entry_lower = entry.lower()
        entry_with_path = os.path.join(path, entry)
        if os.path.isdir(entry_with_path):
            for sub_entry in get_zip_files(entry_with_path, start_pattern):
                yield sub_entry
        else:
            if entry_lower.startswith(start_pattern_lower) and entry_lower.endswith(".zip"):
                yield entry_with_path
0 голосов
/ 03 февраля 2019

К сожалению, у меня нет опыта работы с zip-модулем, но если вы спрашиваете, как вы могли бы перейти к каждой из этих папок, я бы подошел к такой проблеме:

import os
import zipfile

main_file = 'C:\\Users\\Folder1' #wherever you have saved all this data in full path form
os.chdir(main_file) # Load program into top level
os.mkdir('OUTPUT') # make a folder to save output
try:
    for i in range(2010, 2016 + 1): # for years 2010-2016
        os.chdir(str(i))
        for j in range(1, 12+1): # months 1-12
            os.chdir('MMSDM_{0}_{1:02d}'.format(i, j))
            os.chdir('MMSDM_Historical_Data_SQLLoader/DATA')
            z = zipfile.ZipFile('PUBLIC_*.zip')
            # do stuff with zip file here
            os.chdir(main_file)
            os.chdir('OUTPUT')
            with open('FileNameUsingIorJ.csv/zip/SomeOtherExtension', 'w+') as file:
                file.write(zipfile_data)
            os.chdir(main_file) # reset for next loop
except Exception as e:
    print('Exception occurred: {}'.format(e))

Я не могу проверитьэто работает, хотя, потому что у меня, очевидно, нет файлов на моем ПК, и все еще есть некоторые пробелы, такие как "# делать вещи здесь", но, надеюсь, это может помочь вам в правильном направлении!Дайте мне знать, если вам нужно больше разъяснений.

...