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

我有一个日志文件列表,其中每个文件中的每一行都有一个时间戳,并且行在每个文件中按升序排列.不同的文件可以有重叠的时间范围,我的目标是将它们组合成一个大文件,按时间戳排序.在排序中可能存在联系,在这种情况下,我希望下一行来自我输入列表中首先列出的任何文件.
我已经看到了如何使用fileinput执行此操作的示例(请参阅here),但这似乎将所有文件读入内存.由于我的文件很大,这将是一个问题.因为我的文件是预先排序的,所以似乎应该有一种方法来合并它们,使用的方法只需要考虑每个文件中最新的未探索行.
解决方法:
如果标准库中有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()变得很懒,所以你可以使用那个)
本文标题为:python – 合并预先排序的文件而不将所有内容读入内存


基础教程推荐
- centos7安装python3 以及tab补全功能 2023-09-03
- 如何更改Ubuntu 16.04 默认Python版本方法 2023-09-05
- python-无需物理移动即可在进程之间共享数据 2023-11-14
- python-Linux:os.pipe()中的文件描述符未出现在/ dev / fd中 2023-11-11
- Python入门教程之运算符重载详解 2022-10-20
- 如何从python ctypes中取消引用内存位置? 2023-11-15
- Python解决多进程间访问效率低的方法总结 2022-10-20
- linux-python错误“ AttributeError:’模块’对象没有属性’sha1’” 2023-11-12
- python-即使子进程已关闭,MultiProcessing Pipe recv也会阻塞 2023-11-14
- 如何将数据从Python中的不同本地/远程进程流式传输到程序的STDIN中? 2023-11-15