2011-12-31 18 views
5

: BuradaÖzü dosyaları dizin yapısını tutarken bir zip dosyası dosyaları ayıklamak için geçerli kod kullanıyorum

zip_file = zipfile.ZipFile('archive.zip', 'r') 
zip_file.extractall('/dir/to/extract/files/') 
zip_file.close() 

için bir yapıdır bir örnek zip dosyası:

/dir1/file.jpg 
/dir1/file1.jpg 
/dir1/file2.jpg 

sonunda Şunu istiyorum:

/dir/to/extract/file.jpg 
/dir/to/extract/file1.jpg 
/dir/to/extract/file2.jpg 

Ama ben gerektiği zip dosyası içindeki tüm dosyaları ile bir üst düzey klasörü vardır, bu yüzden gnore yalnızca bu yapıyla bir zip ayıklamak zaman:

/dir1/file.jpg 
/dir1/file1.jpg 
/dir1/file2.jpg 
/dir2/file.txt 
/file.mp3 

Şöyle kalmalıdır:

/dir/to/extract/dir1/file.jpg 
/dir/to/extract/dir1/file1.jpg 
/dir/to/extract/dir1/file2.jpg 
/dir/to/extract/dir2/file.txt 
/dir/to/extract/file.mp3 

Herhangi fikirleri ?

cevap

1

Aynı dizinde bulunup bulunmadığını görmek için ZipFile.namelist() tarafından döndürülen girdileri okuyun ve ardından her girişi açın/okuyun ve open() ile açılan bir dosyaya yazın.

0

Bu, zip arşivinin kendisinde bir sorun olabilir. Bir python isteminde, dosyaların zip dosyasında doğru dizinlerde olup olmadığını görmek için bunu deneyin.

import zipfile 

zf = zipfile.ZipFile("my_file.zip",'r') 
first_file = zf.filelist[0] 
print file_list.filename 

Bu durum böyle yüzden first_file = zf.filelist[1] gibi filelist içine çıktı 'dizin1/file1.jpg' gibi görünmelidir Bu defa ikame ve 1 indeksi yukarıdaki adımlar değilse tekrarı "dir1" gibi bir şey demeliyim daha sonra zip dosyası dizin içermez ve tüm dosyaları tek bir dizine açar.

4

Sorunuzu doğru bir şekilde anlıyorsam, bunları önizlemeden önce yaygın önek dizinlerini fermuardaki öğelerden ayırmak istersiniz.

import sys, os 
from zipfile import ZipFile 

def get_members(zip): 
    parts = [] 
    # get all the path prefixes 
    for name in zip.namelist(): 
     # only check files (not directories) 
     if not name.endswith('/'): 
      # keep list of path elements (minus filename) 
      parts.append(name.split('/')[:-1]) 
    # now find the common path prefix (if any) 
    prefix = os.path.commonprefix(parts) 
    if prefix: 
     # re-join the path elements 
     prefix = '/'.join(prefix) + '/' 
    # get the length of the common prefix 
    offset = len(prefix) 
    # now re-set the filenames 
    for zipinfo in zip.infolist(): 
     name = zipinfo.filename 
     # only check files (not directories) 
     if len(name) > offset: 
      # remove the common prefix 
      zipinfo.filename = name[offset:] 
      yield zipinfo 

args = sys.argv[1:] 

if len(args): 
    zip = ZipFile(args[0]) 
    path = args[1] if len(args) > 1 else '.' 
    zip.extractall(path, get_members(zip)) 
+0

Eğer burada neler olduğunu daha iyi anlayabilmek için bazı yorumlar lütfen ekleyebilir miyim: Eğer öyleyse

, sonra aşağıdaki komut istediğini yapmalıdır? – aturegano

+1

@aturegano. Örnek koduna bazı yorumlar ekledim. Zipinfo nesnelerinin dosya isimleri yazılabilir. Böylece komut dosyası, hedef dizine çıkarmadan önce, arşivdeki tüm dosyaların ortak önekini çıkarır. – ekhumoro