2017-09-14 24 views
5

Tôi có một thư mục đầu ds237 trong đó có nhiều thư mục con dưới nó như sau:Python nén nhiều thư mục vào một file 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

tôi đang cố gắng để tạo ra nhiều file zip (với tên zip thích hợp) từ ds237 theo kích thước của tệp zip. sub01-01.zip: contain sub-01 to sub-07 sub08-13.zip : it contains sub08 to sub-13

Tôi đã viết một logic mà tạo ra một danh sách các thư mục con [sub-01,sub-02, sub-03, sub-04, sub-05]. Tôi đã tạo danh sách để tổng kích thước của tất cả các thư mục con trong danh sách không được> 5gb.

Câu hỏi của tôi: là làm thế nào tôi có thể viết một hàm để zip các tiểu dirs (mà nằm trong danh sách) vào một tập tin zip đến với tên riêng. Về cơ bản tôi muốn viết một hàm như sau:

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

Tôi linux tôi thường đạt được điều này bằng cách: 'zip -r nén/sub01-08.zip ds237/sub-0 [1-8] '

Trả lời

6

Nhìn vào https://stackoverflow.com/a/1855118/375530, bạn có thể tái sử dụng chức năng của câu trả lời đó để thêm một thư mục để một 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() 

Các zipit chức năng nên được gọi với danh sách trước chunked của bạn và một tên nhất định. Bạn có thể sử dụng định dạng chuỗi nếu bạn muốn sử dụng tên có lập trình (ví dụ: "path/to/zipfile/sub{}-{}.zip".format(start, end)).

+0

sự kịch bản trên sẽ tạo tệp zip bằng cách loại trừ đường dẫn của thư mục. Giả sử tôi zip '/ Users/aba/ds100/sub-0 [1-6]' vào 'sub01-06.zip' sau đó khi tôi giải nén mã zip, nó sẽ tạo đường dẫn sau' ds100/sub-01' và các thư mục khác. – learnningprogramming

+0

Bạn cũng có thể thay đổi 'relpath' để đi hai thư mục từ' đường dẫn'. Vì vậy, thay đổi 'os.path.join (path, '..')' thành 'os.path.join (đường dẫn, '..', '..')' và nó sẽ hoạt động. – Jerr

+0

nó thực hiện công việc một phần nhưng khi tôi giải nén 'sub01-06.zip' và' sub07-09.zip', lý tưởng nó nên giải nén vào '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, Tuy nhiên trên kịch bản với chnages bạn đề nghị thùng hai khác nhau 'ds100' – learnningprogramming

1

bạn có thể sử dụng subprocess gọi 'zip' và đi qua các con đường như các đối số

+0

tôi có ý định làm điều này theo cách pythonic – learnningprogramming

1

Sau đây sẽ cung cấp cho bạn nén tập tin với một thư mục đầu tiên 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") 

Ví dụ sub01-05.zip sẽ có một cấu trúc tương tự như:

ds100 
├── sub-01 
| ├── 1 
|  ├── 2 
| ├── 1 
| ├── 2 
├── sub-02 
    ├── 1 
     ├── 2 
    ├── 1 
    ├── 2 
Các vấn đề liên quan