Удаление строки в файле

У меня проблема с программой отслеживания времени, когда я пытаюсь идентифицировать строку в файле, перебирая ее, а затем записывая строки, ЕСЛИ в ней нет чего-либо с переменной «удалить», по какой-то причине она проходит через файл и сказать, что он удален, но цикл не удаляет строки.

date = input(" What is today's date? month-day-year format please. (E.G. 01-14-2003) ")
if os.path.exists(date):
    today = open(date, "r")
    print(today.read())

    delete = input(" Which appointment would you like to delete? (Please type the time E.G. 7:00) ")

    #Open the file, save the read to a variable, iterate over the file, check to see if the time is what user entered, if it is not then write it to the line, close the file.

    fileEdit = open(date, "r+")
    for line in today.readline():
        print(line)
        if delete not in line:
            fileEdit.write(line)
    print(fileEdit.read())
    today.close()
    fileEdit.close()
    print ("Appointment deleted, goodbye")

person Dirk Dunn    schedule 06.11.2013    source источник
comment
Это if delete not in line: когда-нибудь False? Попробуйте это, вставив: else: print 'Deleting line.'. Также открывайте такие файлы: with open('filename.txt', 'w') as f:.   -  person Aleksander Lidtke    schedule 07.11.2013


Ответы (4)


Это чтение до конца файла

print(today.read())

Когда вы начинаете повторять здесь, вы уже в конце

for line in today.readline():

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

Другая проблема заключается в том, что вы перебираете первую строку. Вы, вероятно, имели в виду

for line in today:

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

Лучше написать временный файл и заменить.

Если файлы очень маленькие, вы можете прочитать файл в список в памяти, а затем снова перезаписать файл.

Лучшей идеей, прежде чем заходить слишком далеко, является использование базы данных, такой как модуль sqlite (который встроен в Python).

person John La Rooy    schedule 06.11.2013

today.readline() возвращает одну строку. Цикл for перебирает символы в этой строке. И, как указал @gnibbler, файл today находится в конце файла во время вызова today.readline() (поэтому он возвращает пустая строка).

В общем, чтобы удалить что-то в середине файла, нужно полностью заменить файл. Модуль fileinput может помочь:

import fileinput

for line in fileinput.input([date], inplace=1):
    if delete not in line:
       print line, # stdout is redirected to the `date` file

Вот почти то же самое, но без fileinput:

import os
from tempfile import NamedTemporaryFile

filename = date
dirpath = os.path.dirname(filename)
with open(filename) as file, NamedTemporaryFile("w", dir=dirpath) as outfile:
    for line in file:
        if delete not in line:
           print >>outfile, line, # copy old content
    outfile.delete = False # don't delete outfile
os.remove(filename) # rename() doesn't overwrite on Windows
os.rename(outfile.name, filename) # or just `os.replace` in Python 3.3+
person jfs    schedule 06.11.2013

Проблема возникает из-за чтения и записи одного и того же файла. Вот некоторые пояснения по этому поводу.

Хороший справочник (Python для начинающих: чтение и запись в один и тот же файл < /а>)

Таким образом, в режиме r+ и чтение, и запись в файл перемещают указатель файла вперед.

Итак, давайте посмотрим на ваш пример. Сначала вы делаете readline. Это перемещает указатель файла на следующую строку. Вы проверяете, является ли строка, которую вы только что прочитали, действительной или нет, и записываете ее, если это так.

Проблема в том, что вы просто перезаписали следующую строку, а не предыдущую! Итак, ваш код действительно портит ваши данные.

По сути, это очень сложно (и неэффективно, если файл большой) делать то, что вы хотите делать правильно. Вы не можете произвольно удалять байты из середины файла. Для каждой строки, которую вы хотите удалить, вам придется записать поверх нее остальные данные, а затем обрезать файл в конце, чтобы удалить освобожденное пространство.

Вы должны последовать совету других ответов и либо вывести в другой файл, либо stdout.

person korylprince    schedule 06.11.2013

Ну, вы также можете сделать следующее:

with open("input.txt",'r') as infile, open("output.txt",'w') as outfile: 
    # code here

    outfile.write(line)

В вашем файловом цикле вы можете сделать что-то вроде:

if delete:
   continue

чтобы пропустить строку, которую вы не хотите записывать в выходной файл.

person min    schedule 06.11.2013