Лучший способ удалить строку в файле с Python? - PullRequest
0 голосов
/ 25 мая 2011

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

f = open('./todo.txt', 'r')
newF = open('./todo-run.txt', 'a')
lines = f.readlines()
cLine = lines[int(index) - 1]

for line in lines:
  if line != cLine:
    newF.write(line)
f.close()
newF.close()
os.remove('./todo.txt')
shutil.move('./todo-run.txt', './todo.txt')

Ответы [ 4 ]

2 голосов
/ 25 мая 2011

Решение в sed, которое вы можете назвать с помощью «subprocess».Например, для удаления строки 18 сделайте:

sed -i '18 d' filename
1 голос
/ 25 мая 2011

Лучше, чем? Вы можете, например, перетасовать данные в файле, а затем обрезать их, используя меньше памяти, но больше ища (особенно, если вы адаптируете это, чтобы не читать последнюю часть в одном фрагменте):

def cutfile(file, startcut, endcut):
  file.seek(endcut)
  dataafter=file.read()
  file.seek(startcut)
  file.write(dataafter)
  file.truncate()

Или вы не можете удалить старый файл перед переименованием, чтобы получить атомарные обновления. Это действительно зависит от ваших целей.

0 голосов
/ 25 мая 2011

Вы можете перемещать строки после нежелательной строки, перезаписывая одну за раз. Не намного лучше, чем то, что вы сейчас делаете. Этот код выглядит немного забавно, если файл не заканчивается новой строкой. Я тестировал его на Win7 64-bit, Python 2.7.

move_lines.py:

f = open('todo.txt', 'r+')
line_index = 0
prev_line_head = 0
remove_line_index = 3
move_lines = False
while True:
  line_head = f.tell()
  line = f.readline()

  if line == '': #EOF
    f.seek(prev_line_head)
    f.truncate()
    break

  if move_lines:
    f.seek(prev_line_head)
    f.write(line)
    f.flush()
    line_head = f.tell()
    line = f.readline() # read past the line we already read to start this iteration
  elif line_index == remove_line_index:
    move_lines = True
  prev_line_head = line_head
  line_index += 1
f.close()
0 голосов
/ 25 мая 2011

Это не намного лучше, чем у вас, но (поскольку ваш файл, кажется, помещается в основную память), вы можете попробовать это:

f = open(filepath, 'r')
lines = [line.rstrip('\n') for line in f if not <CONDITION>]
f.close()
f.open('filepath, 'w')
f.write('\n'.join(lines))
f.close()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...