我有三个文件:2.gz
文件和1.log
文件。这些文件相当大。下面我有一份原始数据的样本。我想提取与过去24小时相对应的条目。在
a.log.1.gz
2018/03/25-00:08:48.638553 508 7FF4A8F3D704 snononsonfvnosnovoosr
2018/03/25-10:08:48.985053 346K 7FE9D2D51706 ahelooa afoaona woom
2018/03/25-20:08:50.486601 1.5M 7FE9D3D41706 qojfcmqcacaeia
2018/03/25-24:08:50.980519 16K 7FE9BD1AF707 user: number is 93823004
2018/03/26-00:08:50.981908 1389 7FE9BDC2B707 user 7fb31ecfa700
2018/03/26-10:08:51.066967 0 7FE9BDC91700 Exit Status = 0x0
2018/03/26-15:08:51.066968 1 7FE9BDC91700 std:ZMD:
a.log.2.gz
2018/03/26-20:08:48.638553 508 7FF4A8F3D704 snononsonfvnosnovoosr
2018/03/26-24:08:48.985053 346K 7FE9D2D51706 ahelooa afoaona woom
2018/03/27-00:08:50.486601 1.5M 7FE9D3D41706 qojfcmqcacaeia
2018/03/27-10:08:50.980519 16K 7FE9BD1AF707 user: number is 93823004
2018/03/27-20:08:50.981908 1389 7FE9BDC2B707 user 7fb31ecfa700
2018/03/27-24:08:51.066967 0 7FE9BDC91700 Exit Status = 0x0
2018/03/28-00:08:51.066968 1 7FE9BDC91700 std:ZMD:
a.log
2018/03/28-10:08:48.638553 508 7FF4A8F3D704 snononsonfvnosnovoosr
2018/03/28-20:08:48.985053 346K 7FE9D2D51706 ahelooa afoaona woom
** Desired Result**
result.txt
2018/03/27-20:08:50.981908 1389 7FE9BDC2B707 user 7fb31ecfa700
2018/03/27-24:08:51.066967 0 7FE9BDC91700 Exit Status = 0x0
2018/03/28-00:08:51.066968 1 7FE9BDC91700 std:ZMD:
2018/03/28-10:08:48.638553 508 7FF4A8F3D704 snononsonfvnosnovoosr
2018/03/28-20:08:48.985053 346K 7FE9D2D51706 ahelooa afoaona woom
我不知道如何获取过去24小时的条目。在
我想对最近24小时的数据运行下面的函数。在
^{pr2}$
这样的事情应该行得通。在
如果我们制作一些测试日志文件:
^{pr2}$然后运行我们的脚本,它输出预期的结果(对于这个时间点)
处理日志文件通常涉及大量的数据,因此不希望每次都按升序读取,因为这会浪费大量资源。在
我马上想到的实现目标的最快方法(更好的方法肯定会存在)是一个非常简单的随机搜索:我们以相反的顺序搜索日志文件,因此从最新的第一个开始。不是访问所有行,而是任意选择一些
stepsize
,并且只查看每个stepsize
的一些行。这样,您可以在很短的时间内搜索到千兆字节的数据。在此外,这种方法不需要将文件的每一行存储在内存中,而只需要存储一些行和最终结果。在
当
a.log
是当前日志文件时,我们从这里开始搜索:因为我们只对过去24小时感兴趣,所以我们先跳到末尾,然后将要搜索的时间戳保存为格式化字符串:
^{pr2}$现在我们可以开始随机搜索了。你的行看起来平均有65个字符长,因此我们移动了它的倍数。在
有了这段代码,我们只会在最后24小时内搜索每一行
stepsize
(这里:1000行)。一旦我们离开了24小时,我们知道最多我们在文件中走得太远了。在过滤这个“过火”变得非常容易:
由于
contents
覆盖了文件的所有剩余内容(以及lines
所有行,这只是contents
在换行符\n
处拆分),所以我们可以很容易地使用filter
来获得我们想要的结果。在lines
中的每一行都将被馈送给check_line
,如果该行的时间是> timestamp
,则返回{now - 1day
的datetime对象。这意味着check_line
将为所有早于timestamp
的行返回{显然,这远不是最佳的,但它很容易理解,并且很容易扩展到过滤分钟、秒。。。在
此外,覆盖多个文件也很容易:您只需要
glob.glob
来查找所有可能的文件,从最新的文件开始,然后添加另一个循环:您将搜索这些文件,直到while循环第一次失败,然后断开并读取当前文件中的所有剩余内容+之前访问过的所有文件中的所有内容。在大致上是这样的:
这样,您只需存储日志文件的所有行,如果所有行都是<;24小时。如果循环在某个点中断,即我们找到了一个日志文件和一行>;24小时,请将
final_lines
扩展final_result
,因为这将只覆盖24小时的行。在相关问题 更多 >
编程相关推荐