2017-09-14 16 views
5

mam górną katalogu ds237 który ma wiele podkatalogów pod nim, jak poniżej:Python zip wielu katalogów w jednym pliku zip

ds237/ ├── dataset_description.json ├── derivatives ├── sub-01 ├── sub-02 ├── sub-03 ├── sub-04 ├── sub-05 ├── sub-06 ├── sub-07 ├── sub-08 ├── sub-09 ├── sub-10 ├── sub-11 ├── sub-12 ├── sub-13 ├── sub-21 ├── sub-22 ├── sub-23 ├── sub-24 ├── sub-25 ├── sub-26 ├── sub-27 ├── sub-28 ├── sub-29

Próbuję utworzyć wiele plików ZIP (z imion zip) z ds237 zgodnie z rozmiarem plików zip. sub01-01.zip: contain sub-01 to sub-07 sub08-13.zip : it contains sub08 to sub-13

Pisałem logikę, która tworzy listę podkatalogów [sub-01,sub-02, sub-03, sub-04, sub-05]. Utworzyłem listę tak, aby całkowity rozmiar wszystkich podkatalogów na liście nie był> 5 gb.

Moje pytanie: to w jaki sposób można napisać funkcję do zip tych sub-katalogów (które są na liście) do pliku zip docelowego z właściwą nazwą. Zasadniczo chce zapisu funkcji w sposób następujący:

def zipit([list of subdirs], 'path/to/zipfile/sub*-*.zip'):

I Linuksie ogólnie osiągnąć przez: „suwak -r kompresji/sub01-08.zip ds237/sub-0 [1-8] "

Odpowiedz

6

Patrząc na https://stackoverflow.com/a/1855118/375530, można ponownie użyć funkcji tej odpowiedzi, aby dodać katalog do ZipFile.

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(dir_list, zip_name): 
    zipf = zipfile.ZipFile(zip_name, 'w', zipfile.ZIP_DEFLATED) 
    for dir in dir_list: 
     zipdir(dir, zipf) 
    zipf.close() 

Funkcja zipit powinno nazywać się twoim pre-pakietowego listy i danej nazwy. Możesz użyć formatowania ciągów, jeśli chcesz użyć nazwy programowej (np. "path/to/zipfile/sub{}-{}.zip".format(start, end)).

+0

się powyższy skrypt utworzy plik zip, wykluczając ścieżkę katalogu. Powiedzmy, że zamienię '/ Users/aba/ds100/sub-0 [1-6]' na 'sub01-06.zip', a kiedy rozpakuję zip, powinien wygenerować następującą ścieżkę' ds100/sub-01' oraz inne katalogi. – learnningprogramming

+0

Możesz również zmienić 'relpath', aby przejść do dwóch katalogów z' path'. Więc zmień 'os.path.join (path, '..')' na 'os.path.join (path, '..', '..')' i powinno działać. – Jerr

+0

wykonuje to częściowo, ale gdy rozpakowuję 'sub01-06.zip' i' sub07-09.zip', najlepiej powinien on zostać rozpakowany do 'ds100/sub-01 ds100/sub-02 ds100/sub-03 ds100/sub-04 ds100/sub-05 ds100/sub-06 ds100/sub-07 ds100/sub-08 ds100/sub-09, Jednak powyżej skryptu z chnages zasugerował skrzynie dwa różne "ds100" – learnningprogramming

1

Poniższa da Ci plik zip z pierwszego folderu ds100:

import os 
import zipfile  

def zipit(folders, zip_filename): 
    zip_file = zipfile.ZipFile(zip_filename, 'w', zipfile.ZIP_DEFLATED) 

    for folder in folders: 
     for dirpath, dirnames, filenames in os.walk(folder): 
      for filename in filenames: 
       zip_file.write(
        os.path.join(dirpath, filename), 
        os.path.relpath(os.path.join(dirpath, filename), os.path.join(folders[0], '../..'))) 

    zip_file.close() 


folders = [ 
    "/Users/aba/ds100/sub-01", 
    "/Users/aba/ds100/sub-02", 
    "/Users/aba/ds100/sub-03", 
    "/Users/aba/ds100/sub-04", 
    "/Users/aba/ds100/sub-05"] 

zipit(folders, "/Users/aba/ds100/sub01-05.zip") 

Na przykład sub01-05.zip miałby strukturę podobną do:

ds100 
├── sub-01 
| ├── 1 
|  ├── 2 
| ├── 1 
| ├── 2 
├── sub-02 
    ├── 1 
     ├── 2 
    ├── 1 
    ├── 2