Python [面试题] 现在有一个未知大小的日志文件 (可能 100G),要求如果日志文件有包含字符串'error'的行,输出前后 3 行 (包括字符串所在行) 到新的文件中,问怎么实现,用 Python 实现,需要手写到纸上

bozeng · 2020年04月27日 · 最后由 bozeng 回复于 2020年04月29日 · 3720 次阅读

面试中遇到的一个问题,当时答的不好。小伙伴一起来做一下

共收到 11 条回复 时间 点赞

0.0 用链表么

这道题其实考点两个:1)python 读取大文件的方法;2)输出包含 xxx 的上下三行这个功能

  • 读文件:1)分片读取,open("xxx","r").read(1024*1024); 2) with open ...这种方式提取,原理自己百度咯;3)优化:异步、多线程
  • 前后三行这个功能,就要通过通过定义一个计数器来实现了
直接通过 shell 的 grep 来实现,不确定会不会有性能问题

日志过滤用 shell 吧。grep -C 3 error abc.log > new.log

过百 G 的我一般直接就 flink 或者 spark 读了。 python 单线程。。。。这得读到哪辈子去。。。

grep -n 'something' file | tail -n 1
例: grep -n "新增合同 result:" ../logs/catalina.out |tail -n 1

import envoy
r = envoy.run("grep -n "新增合同 result:" ../logs/catalina.out |tail -n 3")
print(r)

o. 差点忘记了 注意转码

python 里直接对 FileObject 循环,应该是直接就是一行一行的读

匿名 #8 · 2020年04月27日

不考虑性能的话,grep 是正解

用 split 切割成 100 个文件然后多个命令 grep 后台执行

个人觉得不用考虑文件大小,说文件太大,是为了不让你把文件全部加载到内存,然后循环遍历,
for line in open() 就是按行读取的,不会全部加载。

问题点是在于,文件只能遍历一次,碰到搜索命中时,后 n 行比较好解决,继续循环就可以了。前三行怎么处理?
这里需要加上一个定长(n=3)的队列,不断 push,超过了长度,就从顶部删除一条。
遇到命中,就全部清空,写到文件中

bozeng #10 · 2020年04月29日 Author
吉吉里 回复

多谢大佬指点,之前我就是没有想到怎么解决前三行的问题

12楼 已删除
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册