Удаление определенной строки в файле (python)

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

13 ответов


предполагая, что ваш файл имеет формат одного псевдонима на строку, используйте это.

Сначала откройте файл:

f = open("yourfile.txt","r")

далее, Получить все строки из файла:

lines = f.readlines()

теперь вы можете закрыть файл:

f.close()

и снова открыть его в режиме записи:

f = open("yourfile.txt","w")

затем напишите свои строки обратно, кроме строки, которую вы хотите удалить. Возможно, вы захотите изменить "\n" к любой строке, заканчивающейся вашим файлом.

for line in lines:
  if line!="nickname_to_delete"+"\n":
    f.write(line)

At конец, закройте файл снова.

f.close()

решение этой проблемы только один:

f = open("target.txt","r+")
d = f.readlines()
f.seek(0)
for i in d:
    if i != "line you want to remove...":
        f.write(i)
f.truncate()
f.close()

Это решение открывает файл в режиме r / w ("r+") и использует seek для сброса F-указателя, а затем усекает, чтобы удалить все после последней записи.


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

with open("yourfile.txt","r") as input:
    with open("newfile.txt","wb") as output: 
        for line in input:
            if line!="nickname_to_delete"+"\n":
                output.write(line)

вот именно! В одном цикле, и только вы можете сделать то же самое. Это будет намного быстрее.


это "вилка" от @Lotherответ (который я считаю, что следует считать правильным ответом).


Для такого файла:

$ cat file.txt 
1: october rust
2: november rain
3: december snow

эта вилка из решения Lother отлично работает:

#!/usr/bin/python3.4

with open("file.txt","r+") as f:
    new_f = f.readlines()
    f.seek(0)
    for line in new_f:
        if "snow" not in line:
            f.write(line)
    f.truncate()

улучшения:

  • with open, которые отбрасывают использование f.close()
  • более яснее if/else для оценки, если строка отсутствует в текущей строке

проблема с чтением строк в первом проходе и внесением изменений (удаление определенных строк) во втором проходе заключается в том, что если размеры файлов огромны, у вас закончится ОЗУ. Вместо этого лучше читать строки одну за другой и записывать их в отдельный файл, исключая те, которые вам не нужны. Я запустил этот подход с файлами размером 12-50 ГБ, и использование ОЗУ остается почти постоянным. Только циклы CPU показывают, что обработка продолжается.


если вы используете Linux, вы можете попробовать следующий подход.
Предположим, у вас есть текстовый файл с именем animal.txt:

$ cat animal.txt  
dog
pig
cat 
monkey         
elephant  

удалить первую строку:

>>> import subprocess
>>> subprocess.call(['sed','-i','/.*dog.*/d','animal.txt']) 

затем

$ cat animal.txt
pig
cat
monkey
elephant

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

вот как я мог бы это сделать:

import, os, csv # and other imports you need
nicknames_to_delete = ['Nick', 'Stephen', 'Mark']

Я предполагаю, что nicknames.csv содержит такие данные, как:

Nick
Maria
James
Chris
Mario
Stephen
Isabella
Ahmed
Julia
Mark
...

затем загрузите файл в список:

 nicknames = None
 with open("nicknames.csv") as sourceFile:
     nicknames = sourceFile.read().splitlines()

далее, повторите список чтобы соответствовать вашим входам для удаления:

for nick in nicknames_to_delete:
     try:
         if nick in nicknames:
             nicknames.pop(nicknames.index(nick))
         else:
             print(nick + " is not found in the file")
     except ValueError:
         pass

наконец, записать результат обратно в файл:

with open("nicknames.csv", "a") as nicknamesFile:
    nicknamesFile.seek(0)
    nicknamesFile.truncate()
    nicknamesWriter = csv.writer(nicknamesFile)
    for name in nicknames:
        nicknamesWriter.writeRow([str(name)])
nicknamesFile.close()

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

лучший способ скопировать его строка за строкой в новый файл, чем удалить первый или что-то вроде этого


В общем, вы не можете; вы должны написать весь файл снова (по крайней мере, с момента изменения до конца).

в некоторых случаях вы можете сделать лучше, чем это -

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

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

Это, вероятно, перебор для коротких документов (что-нибудь под 100 КБ?).


Мне понравился подход fileinput, как описано в этот ответ: удаление строки из текстового файла (python)

скажем, например, у меня есть файл, в котором есть пустые строки, и я хочу удалить пустые строки, Вот как я его решил:

import fileinput
import sys
for line_number, line in enumerate(fileinput.input('file1.txt', inplace=1)):
    if len(line) > 1:
            sys.stdout.write(line)

Примечание: пустые строки в моем случае имели длину 1


Наверное, вы уже получили правильный ответ,но вот мой. Вместо того, чтобы использовать список для сбора нефильтрованных данных (что readlines() метод), я использую два файла. Один предназначен для хранения основных данных, а второй-для фильтрации данных при удалении определенной строки. Вот код:

main_file = open('data_base.txt').read()    # your main dataBase file
filter_file = open('filter_base.txt', 'w')
filter_file.write(main_file)
filter_file.close()
main_file = open('data_base.txt', 'w')
for line in open('filter_base'):
    if 'your data to delete' not in line:    # remove a specific string
        main_file.write(line)                # put all strings back to your db except deleted
    else: pass
main_file.close()

надеюсь, вы найдете это полезным! :)


сохраните строки файла в списке, затем удалите из списка строку, которую вы хотите удалить, и запишите оставшиеся строки в новый файл

with open("file_name.txt", "r") as f:
    lines = f.readlines() 
    lines.remove("Line you want to delete\n")
    with open("new_file.txt", "w") as new_f:
        for line in lines:        
            new_f.write(line)

возьмите содержимое файла, разделите его по новой строке на кортеж. Затем получите доступ к номеру строки кортежа, присоединитесь к кортежу результата и перезапишите файл.