我正在使用当前代码从 zip 文件中提取文件,同时保持目录结构:
zip_file = zipfile.ZipFile('archive.zip', 'r')
zip_file.extractall('/dir/to/extract/files/')
zip_file.close()
这是一个示例 zip 文件的结构:
/dir1/file.jpg
/dir1/file1.jpg
/dir1/file2.jpg
最后我想要这个:
/dir/to/extract/file.jpg
/dir/to/extract/file1.jpg
/dir/to/extract/file2.jpg
但只有当 zip 文件有一个包含所有文件的顶级文件夹时它才应该忽略,所以当我用这种结构提取 zip 时:
/dir1/file.jpg
/dir1/file1.jpg
/dir1/file2.jpg
/dir2/file.txt
/file.mp3
它应该保持这样:
/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
有什么想法吗?
最佳答案
如果我对你的问题的理解正确,你想在解压缩之前从 zip 中的项目中删除所有常见的前缀目录。
如果是这样,那么下面的脚本应该做你想做的:
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))
关于python - 从 zip 中提取文件而不用 python zipfile 保留顶级文件夹,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8689938/