在 python 中导航一个大的 tar.gz 文件而不先解压它

Navigating a large tar.gz file in python without extracting it first

我看过这个 question 但我还需要其他东西。

我的文件包含大量按变量名组织的文本文件(数十万个)。 像

filename/maxvalue/IDXstation.txt     (with X that goes from 100000 to 200000)
filename/minvalue/IDXstation.txt  
filename/meanvalue/IDXstation.txt 

等等。 问题是我没有 readme.txt 文件告诉我 tar 文件中有多少个文件夹或它们是如何命名的(我编造的)(或每个文件夹中有多少个电台). 现在我只想阅读 filename.tar.gz 的结构并打印类似

的内容
filename/maxvalue/  
filename/minvalue/  
filename/meanvalue/

我需要在 tar 解压文件之前阅读它的结构,因为我只对某些文件夹感兴趣,而不是所有文件夹。

如果我使用

for tarinfo in tar:
    print tarinfo.name

它会打印所有的文件,它们有几十万个,我不想这样,但我不知道如何设置它。

wikipedia page on tar要列出档案中文件的名称,必须通读整个档案并寻找文件 start 的位置。因此,您必须取消tar 数据流才能获取文件名。仅打印预期名称的一种简单方法是使用正则表达式仅保留相关的目录名称。如果您确定目录本身已在 tar 文件中注册,那么类似的内容就足够了:

import re

rx = re.compile('[^/]+\/[^/]\/?$')
...
for tarinfo in tar:
    if rx.match(tarinfo.name):
        print tarinfo.name

如果您不确定扩展目录是否已在 tar 文件中注册,您可以使用不太严格的匹配并将目录部分放入一个集合中。像 :

import re

rx = re.compile('([^/]+\/[^/])\/')
...
names = set()
for tarinfo in tar:
    if rx.match(tarinfo.name):
        names.add(tarinfo.name)
for name in names:
    print name
        print tarinfo.name

要打印 tar 存档中的顶级目录,例如,直到第二级:

#!/usr/bin/env python
import sys
import tarfile

with tarfile.open(sys.argv[1]) as archive:
    for member in archive:
        if member.isdir() and member.name.count('/') < 2:
            print(member.name)

用法:

$ print-top-level-dirs <tar-archive>