Python:反向读取文本文件后遍历行
Python: iterate through lines after reverse reading a text file
我正在使用 Python 3.4。
我有一个这样的日志文件:
10001 ...
10002 * SMTP *
10003 skip me
10004 read me
10005 read me
脚本的目标是以反向模式打开文件,遍历行直到我在其中找到'* SMTP *'(在示例中是第 10002 行),然后我必须返回并跳过一行并阅读接下来的两行(在示例行 10004 和 10005 中)。
我该怎么做?
with open (file) as textfile:
lines = textfile.read().split("\n")
lines.reverse()
if lines.index("* SMTP *"):
Ind = int(lines.index("* SMTP *"))
print lines[Ind-2]
print lines[Ind-3]
break
这只会在您的日志文件中找到最近出现的 * SMTP *,它是脏的,但可以完成工作。
做了一些测试来比较@mhawke mmap 和我的。测试是在 150k 行测试文件上完成的。
mmap
real 0m0.024s
user 0m0.016s
sys 0m0.008s
我的解决方案
real 0m0.038s
user 0m0.026s
sys 0m0.012s
mmap
是个不错的选择:
import mmap
SEARCH_TEXT = b'* SMTP *'
SKIP_LINES = 2
KEEP_LINES = 2
with open('log.txt', 'rb') as f:
log = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ)
n = log.rfind(SEARCH_TEXT)
if n == -1:
print('{!r} not found'.format(SEARCH_TEXT))
else:
log.seek(n)
for i in range(SKIP_LINES):
_ = log.readline()
print(''.join(log.readline().decode() for _ in range(KEEP_LINES)))
输出
10004 read me
10005 read me
此代码映射日志文件,从文件末尾 rfind()
搜索目标字符串 '* SMTP *'
。然后它将文件指针定位到目标字符串(使用 seek()
),消耗 2 条不需要的行,最后读取 2 条感兴趣的行。
mmap
是高效的,因为 OS 为您的应用程序处理数据从磁盘到内存的分页。它不会读取整个文件,因此对于大文件来说是一个很好的策略。
我正在使用 Python 3.4。
我有一个这样的日志文件:
10001 ...
10002 * SMTP *
10003 skip me
10004 read me
10005 read me
脚本的目标是以反向模式打开文件,遍历行直到我在其中找到'* SMTP *'(在示例中是第 10002 行),然后我必须返回并跳过一行并阅读接下来的两行(在示例行 10004 和 10005 中)。
我该怎么做?
with open (file) as textfile:
lines = textfile.read().split("\n")
lines.reverse()
if lines.index("* SMTP *"):
Ind = int(lines.index("* SMTP *"))
print lines[Ind-2]
print lines[Ind-3]
break
这只会在您的日志文件中找到最近出现的 * SMTP *,它是脏的,但可以完成工作。
做了一些测试来比较@mhawke mmap 和我的。测试是在 150k 行测试文件上完成的。
mmap
real 0m0.024s
user 0m0.016s
sys 0m0.008s
我的解决方案
real 0m0.038s
user 0m0.026s
sys 0m0.012s
mmap
是个不错的选择:
import mmap
SEARCH_TEXT = b'* SMTP *'
SKIP_LINES = 2
KEEP_LINES = 2
with open('log.txt', 'rb') as f:
log = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ)
n = log.rfind(SEARCH_TEXT)
if n == -1:
print('{!r} not found'.format(SEARCH_TEXT))
else:
log.seek(n)
for i in range(SKIP_LINES):
_ = log.readline()
print(''.join(log.readline().decode() for _ in range(KEEP_LINES)))
输出
10004 read me 10005 read me
此代码映射日志文件,从文件末尾 rfind()
搜索目标字符串 '* SMTP *'
。然后它将文件指针定位到目标字符串(使用 seek()
),消耗 2 条不需要的行,最后读取 2 条感兴趣的行。
mmap
是高效的,因为 OS 为您的应用程序处理数据从磁盘到内存的分页。它不会读取整个文件,因此对于大文件来说是一个很好的策略。