我有一个日志文件列表,其中每个文件中的每一行都有一个时间戳,并且行在每个文件中按升序排列。 不同的文件可以有重叠的时间范围,我的目标是将它们组合成一个大文件,按时间戳排序。 在排序中可能存在联系,在这种情况下,我希望下一行来自我输入列表中首先列出的任何文件。

我已经看过如何使用fileinput执行此操作的fileinput (请参阅此处 ),但这似乎将所有文件读入内存。 由于我的文件很大,这将是一个问题。 因为我的文件是预先排序的,所以似乎应该有一种方法来合并它们,使用的方法只需要考虑每个文件中最新的未探索行。

#1楼 票数:15 已采纳

如果标准库中有heapq.merge() ,为什么要自己滚动? 不幸的是,它没有提供一个关键的论点 - 你必须做装饰 - 合并 - 不自然的舞蹈你自己:

from itertools import imap
from operator import itemgetter
import heapq

def extract_timestamp(line):
    """Extract timestamp and convert to a form that gives the
    expected result in a comparison
    """
    return line.split()[1] # for example

with open("log1.txt") as f1, open("log2.txt") as f2:
    sources = [f1, f2]
    with open("merged.txt", "w") as dest:
        decorated = [
            ((extract_timestamp(line), line) for line in f)
            for f in sources]
        merged = heapq.merge(*decorated)
        undecorated = imap(itemgetter(-1), merged)
        dest.writelines(undecorated)

上面的每一步都是“懒惰”。 当我避免使用file.readlines() ,会根据需要读取文件中的行。 同样,装饰过程使用生成器表达式而不是list-comps。 heapq.merge()很懒惰 - 每个输入迭代器需要一个项目来进行必要的比较。 最后我使用的是itertools.imap() ,它是内置的undecorate的map()的惰性变体。

(在Python 3中map()变得很懒,所以你可以使用那个)

#2楼 票数:1

您想要实现基于文件的合并排序 从两个文件中读取一行,输出旧行,然后从该文件中读取另一行。 一旦其中一个文件耗尽,输出另一个文件中的所有剩余行。

  ask by Abiel translate from so

未解决问题?本站智能推荐:

2回复

合并两个文件,用数字排序,每行一个整数,不读入内存,也不进行排序

我有两个文件,file1和file2,按列2按数字排序: 文件1 文件2 我想合并它们并得到这个输出,它也按第2列数字排序: 我可以使用此unix命令来执行此操作,该命令不会排序,但会合并预先排序的文件: 但是如何在没有将文件读入内存且没有排序的情况下在Python 3.4中
7回复

在Python中将RAR文件的内容读入内存

我正在寻找一种方法从rar存档读取特定文件到内存。 具体来说,它们是编号图像文件的集合(我正在写一个漫画阅读器)。 虽然我可以简单地解开这些文件并根据需要加载它们(完成时删除它们),但我希望尽可能避免这种情况。 总而言之,如果可能的话,我更喜欢跨平台(Windows / Linux)的解
1回复

使用python将记录附加到csv文件的开头而不将文件读入内存[重复]

这个问题在这里已经有了答案: 在不加载 CSV 的情况下将标题添加到 CSV (3 个答案) 11 个月前关闭。 有没有办法在不将整个文件读入内存的情况下
2回复

如何在python3.2中以相反的顺序读取文件而不将整个文件读入内存?[重复]

这个问题在这里已有答案: 如何从结束 5答案 开始从python中的文件中读取行 我正在使用python3.2解析大小为1到10GB的日志文件,需要搜索具有特定正则表达式的行(某种时间戳),并且我想找到最后一次出现。 我试过用: 这导致了非常糟糕的性能(在好的情况下)和
3回复

读取gzip文件的头部/尾部而不将其读入内存[重复]

可能重复: 如何在不读取其全部内容的情况下拖尾压缩文件? 我有一个7GB的gzip syslog文件,提取到超过25GB。 我需要只检索文件的第一行和最后一行,而不是一次将整个文件读入内存。 Python 2.7中的GzipFile()允许使用with来读取头部(迭代通过with
3回复

如何从python中的gzip压缩文件中获取随机行而不将其读入内存

假设我有一个531 gig gzip压缩文本文件,其中512 5448 457 601 475行被'\\ n'分割,并希望在没有文件分割的情况下从中获取随机行。 (别担心,它不是那么大;只是想说它是一个巨大的文件,我知道它有多少行。) 我通常如何使用较小的压缩文件: 我在这个主题上发现
9回复

如何重新搜索或重新匹配整个文件而不将其全部读入内存?

我希望能够对整个文件运行正则表达式,但我希望不必一次将整个文件读入内存,因为我将来可能会处理相当大的文件。 有没有办法做到这一点? 谢谢! 澄清:我无法逐行阅读,因为它可以跨越多行。
3回复

使用awk或perl按键对文件进行排序,就像联接一样,而无需预先排序

我想加入两个制表符分隔的文件,但是它们的顺序不同。 我知道用awk可行,但是我不知道怎么做。 这是等效的玩具python代码(如果没有疯狂的解决方法,python对于此任务而言内存太低): 我有两个文件:对于文件1,第2列保存每行的标识符,我不需要5列,然后大约有300万列数据。 对