Подтвердить что ты не робот

Удалить финальную строку в файле с помощью python

Как удалить последнюю строку файла с помощью python?

Пример входного файла:

hello
world
foo
bar

Пример выходного файла:

hello
world
foo

Я создал следующий код, чтобы найти количество строк в файле, но я не знаю, как удалить указанный номер строки. Я новичок в python - так что если есть более простой способ - скажите, пожалуйста.

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

EDIT:

Я понял это с помощью различных ответов: в основном, клубника и что-то, что я видел в Интернете (извините, я не могу найти ссылку).

#!/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()
4b9b3361

Ответ 1

Вы можете использовать вышеуказанный код, а затем: -

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

Это даст вам массив строк, содержащих все строки, но последний.

Ответ 2

Поскольку я регулярно работаю со многими гигабайтными файлами, цикл, как упоминалось в ответах, не работает для меня. Решение, которое я использую:

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

#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()

file.close()

Ответ 3

Это не использует python, но python - неправильный инструмент для задания, если это единственная задача, которую вы хотите. Вы можете использовать стандартную утилиту * nix head и запустить

head -n-1 filename > newfile

который скопирует все, кроме последней строки имени файла, в новый файл.

Ответ 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, каждая итерация выводит предыдущую строку итераций.

Ответ 5

В системах, где 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".

Ответ 6

Вдохновляя предыдущие сообщения, я предлагаю следующее:

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

Хотя я не тестировал его (пожалуйста, не ненавидите это), я считаю, что есть более быстрый способ его перевести. Это скорее решение C, но вполне возможно в Python. Это тоже не Pythonic. Это теория, я бы сказал.

Во-первых, вам нужно знать кодировку файла. Установите переменную в число байтов, в котором используется символ (1 байт в ASCII). CHARsize (почему бы и нет). Вероятно, будет 1 байт с файлом ASCII.

Затем возьмите размер файла, установите для него FILEsize.

Предположим, что у вас есть адрес файла (в памяти) в FILEadd.

Добавьте FILEsize в FILEadd.

Переместить назад слова (приращение на -1 *** CHARsize **), тестирование каждого байта CHARsize для \n (или любой новой строки, используемой вашей системой). Когда вы достигнете первого \n, теперь у вас есть позиция начала первой строки файла. Замените \n на\x1a (26, ASCII для EOF или что-то другое, что является вашей системой/с кодировкой).

Очистите, однако, вам нужно (изменить размер файла, коснуться файла).

Если это работает так, как я подозреваю, это позволит вам сэкономить много времени, так как вам не нужно читать весь файл с самого начала, вы читаете его с конца.

Ответ 8

здесь другой способ, не опуская весь файл в память

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

Ответ 9

Здесь приведено более общее решение для экономии памяти, позволяющее пропустить последние "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()

Ответ 10

вот мое решение для пользователей Linux:

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

Не нужно читать и перебирать файл в python.