有效地找到文本文件中的最后一行

Tim*_*man 31 python text

我需要从一些非常大(几百兆字节)的文本文件中提取最后一行来获取某些数据.目前,我使用python循环遍历所有行,直到文件为空,然后我处理返回的最后一行,但我确信有一种更有效的方法来执行此操作.

使用python检索文本文件的最后一行的最佳方法是什么?

sth*_*sth 35

不是直接的方式,但可能比简单的Python实现快得多:

line = subprocess.check_output(['tail', '-1', filename])
Run Code Online (Sandbox Code Playgroud)

  • 您需要在末尾添加[0:-1],以某种方式在末尾添加'\ n'... (2认同)
  • 这不是一个非常蟒蛇的解决方案 (2认同)
  • @John9631,你的解决方案非常慢,因为 readlines() 正在读取 RAM 中的所有行,如果文件大小以 GB 为单位,那将给出 MEMORY 错误! (2认同)
  • Windows 支持 `tail` 吗? (2认同)

小智 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)

  • 当您处理GB文本文件时,效果不是很好,而您所需要的只是最后一行检查。 (6认同)
  • 我认为这在处理非常大的文本文件时效率不高。 (4认同)

Mik*_*one 8

使用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命令一样).


Mar*_*som 6

如果您可以选择合理的最大行长度,则可以在开始阅读之前查找到几乎文件的末尾。

myfile.seek(-max_line_length, os.SEEK_END)
line = myfile.readlines()[-1]
Run Code Online (Sandbox Code Playgroud)


roc*_*ker 5

如果你知道一条线的最大长度,你可以这样做

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(),则需要二进制模式.

  • 如果你不知道最大线长? (2认同)

Bry*_*ley 5

寻找文件的末尾减去100个字节左右.读取并搜索换行符.如果这里没有换行符,请再追回100个字节左右.泡沫,冲洗,重复.最终你会找到换行符.最后一行在该换行符后立即开始.

最好的情况是你只读一个100字节.