Python:从tar.gz中提取符合特定模式的文件,而无需提取完整文件

6
我希望从许多tar.gz文件中提取所有带有模式*_sl_H*的文件,而不必提取档案中的所有文件。
我找到了这些行,但无法使用通配符(https://pymotw.com/2/tarfile/):
import tarfile
import os

os.mkdir('outdir')
t = tarfile.open('example.tar', 'r')
t.extractall('outdir', members=[t.getmember('README.txt')])
print os.listdir('outdir')

有人有想法吗? 非常感谢。

2个回答

14

请看TarFile.getmembers()方法,它将以列表形式返回存档文件的成员。获取到该列表后,您可以根据条件决定要提取哪个文件。

import tarfile
import os

os.mkdir('outdir')
t = tarfile.open('example.tar', 'r')
for member in t.getmembers():
    if "_sl_H" in member.name:
        t.extract(member, "outdir")

print os.listdir('outdir')

对于使用tarfile模块给出+1,确实是最佳选择。不过我不确定仅提取tar.gz成员时的性能,因为整个归档文件都被gz压缩,可能需要在内存中提取所有内容才能访问归档成员。 - Pierre-Selim

9
您可以按照以下步骤从多个tar文件中提取符合您模式的所有文件:
  1. 使用 glob 获取给定文件夹中所有 *.tar*.gz 文件的列表。

  2. 对于每个tar文件,使用 getmembers() 函数获取每个tar文件中的文件列表。

  3. 使用正则表达式(或简单的 if "xxx" in 测试)来过滤所需的文件。

  4. 将匹配文件的列表传递给 extractall() 函数中的 members 参数。

  5. 添加异常处理以捕获编码不良的tar文件。

例如:
import tarfile
import glob
import re

reT = re.compile(r'.*?_sl_H.*?')

for tar_filename in glob.glob(r'\my_source_folder\*.tar'):
    try:
        t = tarfile.open(tar_filename, 'r')
    except IOError as e:
        print(e)
    else:
        t.extractall('outdir', members=[m for m in t.getmembers() if reT.search(m.name)])

我认为该库不支持从tar归档中删除文件。要做到这一点,您需要创建一个新的tar文件,其中不包含提取的文件。 - Martin Evans
好的,感谢快速回复。那么,在提取相关文件后删除“active”tar.gz文件是不可能的吗?否则我会遇到存储问题。 - asator
要删除整个tar文件,请尝试在提取之后并在os.remove()之前添加t.close() - Martin Evans
太好了,谢谢!还有一件事。是否可以将带有“_sl_HH”模式的文件提取到输出目录中,将所有带有“_sl_HV”模式的文件压缩成一个新的归档文件,然后删除“活动”的tar.gz文件?由于我正在普通PC上工作,多核处理怎么样?我需要在HDD上总共处理约2TB的数据。 - asator
请查看此问题,了解如何使用Python创建完整压缩的tar文件:https://dev59.com/TnI-5IYBdhLWcg3wED9V - Martin Evans

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接