Ответ 1
Вы можете использовать вышеуказанный код, а затем: -
lines = file.readlines()
lines = lines[:-1]
Это даст вам массив строк, содержащих все строки, но последний.
Как удалить последнюю строку файла с помощью 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()
Вы можете использовать вышеуказанный код, а затем: -
lines = file.readlines()
lines = lines[:-1]
Это даст вам массив строк, содержащих все строки, но последний.
Поскольку я регулярно работаю со многими гигабайтными файлами, цикл, как упоминалось в ответах, не работает для меня. Решение, которое я использую:
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()
Это не использует python, но python - неправильный инструмент для задания, если это единственная задача, которую вы хотите. Вы можете использовать стандартную утилиту * nix head
и запустить
head -n-1 filename > newfile
который скопирует все, кроме последней строки имени файла, в новый файл.
Предполагая, что вам нужно сделать это на 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, каждая итерация выводит предыдущую строку итераций.
В системах, где 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".
Вдохновляя предыдущие сообщения, я предлагаю следующее:
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()
Хотя я не тестировал его (пожалуйста, не ненавидите это), я считаю, что есть более быстрый способ его перевести. Это скорее решение C, но вполне возможно в Python. Это тоже не Pythonic. Это теория, я бы сказал.
Во-первых, вам нужно знать кодировку файла. Установите переменную в число байтов, в котором используется символ (1 байт в ASCII). CHARsize (почему бы и нет). Вероятно, будет 1 байт с файлом ASCII.
Затем возьмите размер файла, установите для него FILEsize.
Предположим, что у вас есть адрес файла (в памяти) в FILEadd.
Добавьте FILEsize в FILEadd.
Переместить назад слова (приращение на -1 *** CHARsize **), тестирование каждого байта CHARsize для \n (или любой новой строки, используемой вашей системой). Когда вы достигнете первого \n, теперь у вас есть позиция начала первой строки файла. Замените \n на\x1a (26, ASCII для EOF или что-то другое, что является вашей системой/с кодировкой).
Очистите, однако, вам нужно (изменить размер файла, коснуться файла).
Если это работает так, как я подозреваю, это позволит вам сэкономить много времени, так как вам не нужно читать весь файл с самого начала, вы читаете его с конца.
здесь другой способ, не опуская весь файл в память
p=""
f=open("file")
for line in f:
line=line.strip()
print p
p=line
f.close()
Здесь приведено более общее решение для экономии памяти, позволяющее пропустить последние "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()
вот мое решение для пользователей Linux:
import os
file_path = 'test.txt'
os.system('sed -i "$ d" {0}'.format(file_path))
Не нужно читать и перебирать файл в python.