использование Python для удаления определенной строки в файле - PullRequest
122 голосов
/ 17 января 2011

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

Ответы [ 15 ]

167 голосов
/ 17 января 2011

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

with open("yourfile.txt", "r") as f:
    lines = f.readlines()
with open("yourfile.txt", "w") as f:
    for line in lines:
        if line.strip("\n") != "nickname_to_delete":
            f.write(line)

Вам нужно strip("\n") символ новой строки в сравнении, потому что, если ваш файл не заканчивается символом новой строки, самый последний line тоже не будет.

82 голосов
/ 21 января 2015

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

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

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

21 голосов
/ 13 ноября 2014

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

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

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

18 голосов
/ 25 июля 2017

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


Для файла, подобного этому:

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

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

#!/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 для оценки отсутствия строки в текущей строке
4 голосов
/ 07 ноября 2013

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

3 голосов
/ 27 февраля 2016

Если вы используете 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
2 голосов
/ 24 апреля 2016

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

Вот как я могу это сделать:

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

I 'm при условии, что 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()
2 голосов
/ 14 апреля 2015

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

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

2 голосов
/ 13 января 2015

Мне понравился подход 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

1 голос
/ 25 ноября 2015

Возможно, вы уже получили правильный ответ, но здесь мой. Вместо использования списка для сбора нефильтрованных данных (что делает метод 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()

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...