不解压缩40GB tar.gz文件,如何确定其行数?

4

你是在寻找一种特别使用Python来实现的方法吗? - JJJ
你无法强制要求,但你可以建议生产者将那个信息添加到名称中,这样你就不必自己去解决了。 - Alessandro Santini
1
要计算行数,您需要在某个时候解压文件的每个部分。但是,您可以分块处理它,而不是一次性解压整个文件。选择适合内存的块大小,文件大小就不是问题了。这是您要求的内容吗(如何分块处理.tar.gz文件)? - Blckknght
是的,我需要在Python中完成它@Juhana。 - Geet
@Blckknght:我该如何分块解压.tar.gz文件,读取数据,并以迭代方式将其写入CSV? - Geet
2个回答

3
如果tar.gz中只有一个CSV文件,您可以使用以下Bash一行代码: tar -zxOf mysql-2016-06-16.tar.gz | wc -l 它使用tar将归档中的所有文件提取到标准输出(-O, 大写字母O, 不是零),并使用wc计算行数。
如果有多个文件,而且只想要其中一个文件,您可以像这样计算该文件的行数: tar -zxOf mysql-2016-06-16.tar.gz mysql-2016-06-16/commit_comments.csv| wc -l 以下是如何列出归档中的所有文件: tar -zlf mysql-2016-06-16.tar.gz CSV文件通常有标题,因此每个文件删除一行即可得到行数。

1

不需要解压整个文件,该文件可能超过100GB

我想你的意思是不先将文件提取到磁盘中。以下是一种Python方法来实现这一点:

import tarfile as tf
import gzip as gz
from StringIO import StringIO
infile = '/path/to/mysql-2016-06-16.tar.gz'
def linecount(infile, member):
    lc = 0
    with gz.GzipFile(infile) as zipf:
        with tf.TarFile(fileobj=zipf) as tarf:
            dataf = tarf.extractfile(member)
            while dataf.readline():
               lc += 1 
            dataf.close()       
    return lc
print linecount(infile, 'test.csv')

它说“找不到文件名为'test.csv'的文件”。 要知道tar文件有哪些成员:
def listmembers(infile):
    with gz.GzipFile(infile) as zipf:
        with tf.TarFile(fileobj=zipf) as tarf:
            return list(m.name for m in tarf)  

计算tar文件中所有文件的行数:

for member in listmembers(infile):
    print member, linecount(infile, member)

在开始之前,了解tar文件的结构将会很有用。


这个程序是实时解压缩还是提取到临时文件中? - Leon
这是一种内存中的即时解压缩技术。 - miraculixx
谢谢@miraculixx提供的代码。我认为我已经接近成功了,但是它显示“找不到文件名为'test.csv'的文件”。我是Python的新手:(。接下来该怎么办? - Geet
@miraculixx:它仍然显示“找不到文件名为'test.csv'”。我需要为上面的代码提供任何有关“member”的信息吗?谢谢! - Geet
1
我可以告诉你,但我认为你会从实际思考我的完整示例代码中受益更多。你正在正确的轨道上。提示:我实际上没有下载你的文件,我制作了自己的tar.gz并包含了一个test.csv。 - miraculixx
1
好的,我会尝试理解。感谢@miraculixx分享详细的代码。实际上,我只学了两周Python,并正在向你们学习迈出第一步。非常感谢你们的耐心! - Geet

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