使用python删除文件中的最后一行

时间:2009-12-10 00:57:01

标签: python text line

如何使用python删除文件的最后一行?

输入文件示例:

hello
world
foo
bar

输出文件示例:

hello
world
foo

我创建了以下代码来查找文件中的行数 - 但我不知道如何删除特定的行号。我是python的新手 - 所以如果有更简单的方法 - 请告诉我。

    try:
        file = open("file")
    except IOError:
        print "Failed to read file."
    countLines = len(file.readlines())

修改

我用各种答案想出来:主要是草莓和我在网上看到的东西(对不起,我找不到链接)。

#!/usr/bin/env python

import os, sys

readFile = open("file")

lines = readFile.readlines()

readFile.close()
w = open("file",'w')

w.writelines([item for item in lines[:-1]])

w.close()

10 个答案:

答案 0 :(得分:61)

因为我经常使用许多千兆字节的文件,所以在答案中提到的循环对我来说不起作用。我使用的解决方案:

with open(sys.argv[1], "r+", encoding = "utf-8") as file:

    # Move the pointer (similar to a cursor in a text editor) to the end of the file
    file.seek(0, os.SEEK_END)

    # This code means the following code skips the very last character in the file -
    # i.e. in the case the last line is null we delete the last line
    # and the penultimate one
    pos = file.tell() - 1

    # Read each character in the file one at a time from the penultimate
    # character going backwards, searching for a newline character
    # If we find a new line, exit the search
    while pos > 0 and file.read(1) != "\n":
        pos -= 1
        file.seek(pos, os.SEEK_SET)

    # So long as we're not at the start of the file, delete all the characters ahead
    # of this position
    if pos > 0:
        file.seek(pos, os.SEEK_SET)
        file.truncate()

答案 1 :(得分:10)

您可以使用上述代码,然后: -

lines = file.readlines()
lines = lines[:-1]

这将为您提供包含除最后一行之外的所有行的数组。

答案 2 :(得分:6)

这不使用python,但如果这是你想要的唯一任务,那么python是错误的工具。您可以使用标准的* nix实用程序head,然后运行

head -n-1 filename > newfile

将除了文件名的最后一行复制到newfile。

答案 3 :(得分:4)

假设您必须在Python中执行此操作并且您有足够大的文件列表切片是不够的,您可以在文件的一次传递中执行此操作:

last_line = None
for line in file:
    if last_line:
        print last_line # or write to a file, call a function, etc.
    last_line = line

这不是世界上最优雅的代码,但它完成了工作。

基本上它通过last_line变量缓冲文件中的每一行,每次迭代都输出前一个迭代行。

答案 4 :(得分:3)

file.truncate()有效的系统上,您可以执行以下操作:

file = open('file.txt', 'rb')
pos = next = 0
for line in file:
  pos = next # position of beginning of this line
  next += len(line) # compute position of beginning of next line
file = open('file.txt', 'ab')
file.truncate(pos)

根据我的测试,file.tell()在逐行读取时不起作用,大概是因为缓冲混淆了它。这就是为什么这会增加线条的长度来计算出位置。请注意,这仅适用于行分隔符以'\ n'结尾的系统。

答案 5 :(得分:2)

这是我的linux用户解决方案:

import os 
file_path = 'test.txt'
os.system('sed -i "$ d" {0}'.format(file_path))

无需在python中读取和遍历文件。

答案 6 :(得分:1)

鼓励以前的帖子,我提出这个:

with open('file_name', 'r+') as f:
  f.seek(0, os.SEEK_END) 
  while f.tell() and f.read(1) != '\n':
    f.seek(-2, os.SEEK_CUR)
  f.truncate()

答案 7 :(得分:0)

虽然我没有测试过(请不要讨厌),我相信有更快的方法。它更像是一个C解决方案,但在Python中很有可能。它也不是Pythonic。我会说,这是一个理论。

首先,您需要知道文件的编码。将变量设置为该编码中使用的字符的字节数(ASCII中为1个字节)。 CHARsize (为什么不呢)。可能是一个带有ASCII文件的1字节。

然后获取文件的大小,将 FILEsize 设置为它。

假设您拥有 FILEadd 中文件的地址(在内存中)。

FILEsize 添加到 FILEadd

移动后备词(递增-1 *** CHARsize **),测试\ n(或系统使用的任何换行符)的每个CHARsize字节。当您到达第一个\ n时,您现在拥有文件第一行开头的位置。将\ n替换为\ x1a(26,EOF的ASCII,或者您的系统/编码的任何内容)。

然后清理你需要(更改文件大小,触摸文件)。

如果我怀疑它会起作用,那么你将节省大量时间,因为你不需要从头开始阅读整个文件,你从头开始阅读。

答案 8 :(得分:0)

这是另一种方式,不会将整个文件压入内存

p=""
f=open("file")
for line in f:
    line=line.strip()
    print p
    p=line
f.close()

答案 9 :(得分:0)

这是一个更通用的内存效率解决方案,允许跳过最后的'n'行(如head命令):

import collections, fileinput
def head(filename, lines_to_delete=1):
    queue = collections.deque()
    lines_to_delete = max(0, lines_to_delete) 
    for line in fileinput.input(filename, inplace=True, backup='.bak'):
        queue.append(line)
        if lines_to_delete == 0:
            print queue.popleft(),
        else:
            lines_to_delete -= 1
    queue.clear()