Ответы:
Сначала откройте файл и получите все свои строки из файла. Затем снова откройте файл в режиме записи и запишите свои строки обратно, за исключением строки, которую вы хотите удалить:
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
не будет.
Решение этой проблемы только с одним открытием:
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-указатель, а затем усечь, чтобы удалить все после последней записи.
for
цикле, вы получите частично перезаписанный файл с дублирующимися линиями или половиной обрезанной строки. Возможно, вы захотите f.truncate()
сразу после f.seek(0)
этого. Таким образом, если вы получите ошибку, вы просто получите неполный файл. Но реальное решение (если у вас есть место на диске) - вывести во временный файл, а затем использовать os.replace()
или pathlib.Path(temp_filename).replace(original_filename)
заменить его оригиналом после того, как все будет успешно.
i.strip('\n') != "line you want to remove..."
как указано в принятом ответе, это прекрасно решило бы мою проблему. Потому что просто i
ничего не сделал для меня
Лучший и самый быстрый вариант, вместо того, чтобы хранить все в списке и заново открывать файл, чтобы записать его, - по моему мнению, переписать файл в другом месте.
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)
Это оно! В одном цикле и только один вы можете сделать то же самое. Это будет намного быстрее.
(output.write(line) for line in input if line!="nickname_to_delete"+"\n")
subprocess.call(['mv', 'newfile.txt', 'yourfile.txt'])
os.replace
(новинка в python v 3.3) более кроссплатформенная, чем системный вызов mv
.
Это "вилка" от @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
для оценки, если строка не присутствует в текущей строкеПроблема с чтением строк на первом проходе и внесением изменений (удалением определенных строк) на втором проходе заключается в том, что если у вас большие размеры файлов, вам не хватит ОЗУ. Вместо этого, лучший подход - читать строки по одной и записывать их в отдельный файл, исключая ненужные. Я использовал этот подход для файлов размером 12-50 ГБ, и использование оперативной памяти остается практически постоянным. Только циклы процессора показывают обработку в процессе.
Мне понравился подход 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
Если вы используете 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 КБ?).
Возможно, вы уже получили правильный ответ, но здесь мой. Вместо того, чтобы использовать список для сбора нефильтрованных данных (что 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)
Вот еще один способ удалить некоторые строки из файла:
src_file = zzzz.txt
f = open(src_file, "r")
contents = f.readlines()
f.close()
contents.pop(idx) # remove the line item from list, by line number, starts from 0
f = open(src_file, "w")
contents = "".join(contents)
f.write(contents)
f.close()
Вы можете использовать
re
библиотеку
Предполагая, что вы можете загрузить свой полный текстовый файл. Затем вы определяете список нежелательных псевдонимов, а затем заменяете их пустой строкой "".
# Delete unwanted characters
import re
# Read, then decode for py2 compat.
path_to_file = 'data/nicknames.txt'
text = open(path_to_file, 'rb').read().decode(encoding='utf-8')
# Define unwanted nicknames and substitute them
unwanted_nickname_list = ['SourDough']
text = re.sub("|".join(unwanted_nickname_list), "", text)
Чтобы удалить конкретную строку файла по номеру строки :
Замените переменные filename и line_to_delete на имя вашего файла и номер строки, которую вы хотите удалить.
filename = 'foo.txt'
line_to_delete = 3
initial_line = 1
file_lines = {}
with open(filename) as f:
content = f.readlines()
for line in content:
file_lines[initial_line] = line.strip()
initial_line += 1
f = open(filename, "w")
for line_number, line_content in file_lines.items():
if line_number != line_to_delete:
f.write('{}\n'.format(line_content))
f.close()
print('Deleted line: {}'.format(line_to_delete))
Пример вывода :
Deleted line: 3
for nb, line in enumerate(f.readlines())
Возьмите содержимое файла, разбейте его на новую строку в кортеж. Затем получите доступ к номеру строки вашего кортежа, присоедините его к кортежу результата и перезапишите файл.
tuple(f.read().split('\n'))
?? (2) «получить доступ к номеру строки вашего кортежа» и «присоединиться к вашему кортежу результата» звучит довольно загадочно; Фактический код Python может быть более понятным.
fileinput
как описано @ JF-Себастьяне здесь . Похоже, что вы можете работать построчно, через временный файл, с простымfor
синтаксисом.