使用python在文件中跳过最后5行

时间:2015-08-31 09:46:42

标签: python

我想使用python删除文件中的最后几行。该文件的大小很大,所以要删除前几行,我正在使用以下代码

import sys
with open(sys.argv[1],"rb") as f:
    for _ in range(6):#skip first 6 lines
        next(f)
    for line in f:
        print line

3 个答案:

答案 0 :(得分:4)

这是一个用于截断任何可迭代的通用生成器:

from collections import deque

def truncate(iterable, num):
    buffer = deque(maxlen=num)
    iterator = iter(iterable)

    # Initialize buffer
    for n in range(num):
        buffer.append(next(iterator))

    for item in iterator:
        yield buffer.popleft()
        buffer.append(item)

truncated_range20 = truncate(range(20), 5)

print(list(truncated_range20))
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

使用truncate,您可以执行此操作:

from __future__ import print_function

import sys

from itertools import islice


filepath = sys.argv[1]

with open(filepath, 'rb') as f:
    for line in truncate(islice(f, 6, None), 5):
        print(line, end='')

答案 1 :(得分:3)

如果每一行都有不同的长度,并且您无法预测何时停止文件大小,那么您的python脚本无法知道。

所以你需要做一些缓冲。更简单的方法是缓冲整个文件,将所有内容拆分成行,然后删除最后5个,但你似乎说不能,因为文件很大。

那么为什么不在内存中只保留最后5行呢?

import sys

with open(sys.argv[1],"rb") as f:
    # Skip 6 lines
    for _ in range(6):
        next(f)

    # Create a list that will contain at most 5 lines.
    # Using a list is not super efficient here (a Queue would be better), but it's only 5 items so...
    last_lines = []
    for line in f:
        # if the buffer is full, print the first one and remove it from the list.
        if len(last_lines) == 5:
            print last_lines.pop(0)

        # append current line to the list.
        last_lines.append(line)

    # when we reach this comment, the last 5 lines will remain on the list.
    # so you can just drop them.

作为旁注,我想你明确表示你想要使用python,因为你想稍后用其他东西替换“打印行”,或者做一些额外的处理。

如果不是,请使用操作系统“head”和“tail”命令(我不知道它们是如何在Windows上命名的),这将更加快速(因为它们使用更好的数据结构,读取和一次处理大块,从末尾扫描文件,不使用python编码等。)

答案 2 :(得分:0)

以下工作很好,适用于非常大的文件。

它打开文件进行更新,跳到几乎结束并将剩余部分读作行。然后它将文件指针移回它开始读取的位置。然后它将除了最后5行之外的所有行写回文件,并截断文件的剩余部分:

import os 

back_up = 5 * 200       # Go back from the end more than 5 lines worth

with open("foo.txt", "r+") as f:
    f.seek(-back_up, os.SEEK_END)
    lines = f.readlines()[:-5]
    f.seek(-back_up, os.SEEK_END)
    f.write("".join(lines))
    f.truncate()

您必须决定每条线的粗略感受。它不需要是一个确切的值,只是足以确保你有最后一行。

例如,如果您的线条非常长,您可以back_up更大的值,例如10 * 10000是安全的。这样可以避免必须处理整个大文件。