我需要从一些非常大(几百兆字节)的文本文件中提取最后一行来获取某些数据.目前,我使用python循环遍历所有行,直到文件为空,然后我处理返回的最后一行,但我确信有一种更有效的方法来执行此操作.
使用python检索文本文件的最后一行的最佳方法是什么?
sth*_*sth 35
不是直接的方式,但可能比简单的Python实现快得多:
line = subprocess.check_output(['tail', '-1', filename])
Run Code Online (Sandbox Code Playgroud)
小智 27
with open('output.txt', 'r') as f:
lines = f.read().splitlines()
last_line = lines[-1]
print last_line
Run Code Online (Sandbox Code Playgroud)
使用seek带有负偏移量的文件方法,并whence=os.SEEK_END从文件末尾读取一个块.在该块中搜索最后一行结束字符并获取其后的所有字符.如果没有行结束,则备份更远并重复该过程.
def last_line(in_file, block_size=1024, ignore_ending_newline=False):
suffix = ""
in_file.seek(0, os.SEEK_END)
in_file_length = in_file.tell()
seek_offset = 0
while(-seek_offset < in_file_length):
# Read from end.
seek_offset -= block_size
if -seek_offset > in_file_length:
# Limit if we ran out of file (can't seek backward from start).
block_size -= -seek_offset - in_file_length
if block_size == 0:
break
seek_offset = -in_file_length
in_file.seek(seek_offset, os.SEEK_END)
buf = in_file.read(block_size)
# Search for line end.
if ignore_ending_newline and seek_offset == -block_size and buf[-1] == '\n':
buf = buf[:-1]
pos = buf.rfind('\n')
if pos != -1:
# Found line end.
return buf[pos+1:] + suffix
suffix = buf + suffix
# One-line file.
return suffix
Run Code Online (Sandbox Code Playgroud)
请注意,这不适用于不支持的内容seek,如stdin或套接字.在那些情况下,你会被困在阅读整个事情(就像tail命令一样).
如果您可以选择合理的最大行长度,则可以在开始阅读之前查找到几乎文件的末尾。
myfile.seek(-max_line_length, os.SEEK_END)
line = myfile.readlines()[-1]
Run Code Online (Sandbox Code Playgroud)
如果你知道一条线的最大长度,你可以这样做
def getLastLine(fname, maxLineLength=80):
fp=file(fname, "rb")
fp.seek(-maxLineLength-1, 2) # 2 means "from the end of the file"
return fp.readlines()[-1]
Run Code Online (Sandbox Code Playgroud)
这适用于我的Windows机器.但是我不知道如果你以二进制模式打开文本文件会在其他平台上发生什么.如果要使用seek(),则需要二进制模式.
寻找文件的末尾减去100个字节左右.读取并搜索换行符.如果这里没有换行符,请再追回100个字节左右.泡沫,冲洗,重复.最终你会找到换行符.最后一行在该换行符后立即开始.
最好的情况是你只读一个100字节.
| 归档时间: |
|
| 查看次数: |
90027 次 |
| 最近记录: |