2011-12-31 15 views
5

estoy usando el código actual para extraer los archivos de un archivo zip, manteniendo la estructura de directorios:Extrae los archivos de ZIP sin guardar la carpeta de nivel superior con el archivo zip pitón

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

Aquí es una estructura de un ejemplo de archivo zip:

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

al final quiero esto:

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

Pero ¿Debo gnore sólo si el archivo zip tiene una carpeta de nivel superior con todos los archivos en su interior, por lo que cuando extraigo una postal con esta estructura:

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

Debe quedar así:

/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 

Todas las ideas ?

Respuesta

1

Lea las entradas devueltas por ZipFile.namelist() para ver si están en el mismo directorio, y luego abra/lea cada entrada y escríbala en un archivo abierto con open().

0

Esto podría ser un problema con el archivo zip en sí. En un mensaje de Python intente esto para ver si los archivos están en los directorios correctos en el archivo zip.

import zipfile 

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

Esto debería decir algo como "dir1" repita los pasos anteriores y la sustitución de índice de 1 en lista de archivos al igual que first_file = zf.filelist[1] Esta vez, la salida debería verse como 'dir1/file1.jpg' si este no es el caso entonces el archivo zip no contiene directorios y se descomprimirá en un solo directorio.

4

Si entiendo su pregunta correctamente, quiere quitar cualquier directorio de prefijo común de los elementos en el zip antes de extraerlos.

Si es así, entonces la siguiente secuencia de comandos debe hacer lo que quiera:

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

de mayo que añadir algunos comentarios con el fin de entender mejor lo que está pasando aquí, por favor? – aturegano

+1

@aturegano. Agregué algunos comentarios al código de ejemplo. Los nombres de archivo de los objetos zipinfo son escribibles. Entonces, la secuencia de comandos elimina el prefijo común de todos los archivos en el archivo, antes de extraerlos al directorio de destino. – ekhumoro

Cuestiones relacionadas