可能重复:
Get last n lines of a file with Python, similar to tail
Read a file in reverse order using python
我有一个大约15GB的文件,它是一个我应该分析输出的日志文件。我已经对一个类似但非常小的文件进行了基本解析,只需几行日志记录。解析字符串不问题。问题是庞大的文件及其包含的冗余数据量。
基本上我正在尝试制作一个我可以说的python脚本;例如,给我5000个文件的最后一行。这又是基本的处理论点和所有这些,没有什么特别的,我可以做到这一点。
但是如何定义或告诉文件阅读器只读取我从文件末尾指定的行数?我试图跳过文件开头的 huuuuuuge 行数,因为我对这些行不感兴趣,说实话,从txt文件读取大约15GB的行需要太长时间。有没有办法犯错误...从文件末尾开始阅读?这甚至有意义吗?
这一切归结为读取15GB文件的问题,一行一行需要太长时间。所以我想在开始时跳过已经冗余的数据(至少对我来说是冗余的),只读取我想要读取的文件末尾的行数。
明显的答案是手动将N行的数量从文件中复制到另一个文件但是有没有办法半自动地神奇地用python读取文件末尾的N行数?
答案 0 :(得分:14)
将其归于unix:
import os
os.popen('tail -n 1000 filepath').read()
如果您需要能够访问stderr(以及其他一些功能),请使用subprocess.Popen而不是os.popen
答案 1 :(得分:12)
你需要寻找文件的 end ,然后从最后的块中读取一些块,计算行数,直到找到足够的换行符来读取n
行
基本上,你正在重新实现一种简单的尾巴形式。
以下是一些经过严格测试的代码:
import os, errno
def lastlines(hugefile, n, bsize=2048):
# get newlines type, open in universal mode to find it
with open(hugefile, 'rU') as hfile:
if not hfile.readline():
return # empty, no point
sep = hfile.newlines # After reading a line, python gives us this
assert isinstance(sep, str), 'multiple newline types found, aborting'
# find a suitable seek position in binary mode
with open(hugefile, 'rb') as hfile:
hfile.seek(0, os.SEEK_END)
linecount = 0
pos = 0
while linecount <= n + 1:
# read at least n lines + 1 more; we need to skip a partial line later on
try:
hfile.seek(-bsize, os.SEEK_CUR) # go backwards
linecount += hfile.read(bsize).count(sep) # count newlines
hfile.seek(-bsize, os.SEEK_CUR) # go back again
except IOError, e:
if e.errno == errno.EINVAL:
# Attempted to seek past the start, can't go further
bsize = hfile.tell()
hfile.seek(0, os.SEEK_SET)
pos = 0
linecount += hfile.read(bsize).count(sep)
break
raise # Some other I/O exception, re-raise
pos = hfile.tell()
# Re-open in text mode
with open(hugefile, 'r') as hfile:
hfile.seek(pos, os.SEEK_SET) # our file position from above
for line in hfile:
# We've located n lines *or more*, so skip if needed
if linecount > n:
linecount -= 1
continue
# The rest we yield
yield line
答案 2 :(得分:-1)
即使我更喜欢'tail'解决方案 - 如果您知道每行的最大字符数,您可以通过获取文件大小来实现另一种可能的解决方案,打开文件处理程序并使用'seek'方法您正在寻找的一些估计字符数。
这个最终的代码应该看起来像这样 - 只是为了解释为什么我也更喜欢尾部解决方案:) goodluck!
MAX_CHARS_PER_LINE = 80
size_of_file = os.path.getsize('15gbfile.txt')
file_handler = file.open('15gbfile.txt', "rb")
seek_index = size_of_file - (number_of_requested_lines * MAX_CHARS_PER_LINE)
file_handler.seek(seek_index)
buffer = file_handler.read()
您可以通过分析您阅读的缓冲区的换行符来改进此代码。 祝你好运(你应该使用尾部解决方案;-)我很确定你可以获得每个操作系统的尾部)
答案 3 :(得分:-2)
此时的首选方法是使用unix的尾部作为作业,并修改python以通过std输入接受输入。
tail hugefile.txt -n1000 | python magic.py
这没什么性感,但至少它会照顾这份工作。我发现,大文件是一个太大的负担。至少对我的python技能。因此,只需添加一点nix魔法来减少文件大小就容易多了。尾巴对我来说是新的。了解了一些东西,并找出了再次使用终端的另一种方式。谢谢大家。