Відповіді:
Спочатку відкрийте файл і отримайте з нього всі рядки. Потім знову відкрийте файл у режимі запису та запишіть рядки назад, за винятком рядка, який потрібно видалити:
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-pointer, а потім усікати, щоб видалити все після останнього запису.
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
Ця вилка з рішення 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 ГБ, і використання оперативної пам’яті залишається майже постійним. Лише цикли процесора показують процес обробки.
Мені сподобався файловий підхід, як пояснено у цій відповіді: Видалення рядка з текстового файлу (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
бібліотеку
Якщо припустити, що ви можете завантажити повний txt-файл. Потім ви визначаєте список небажаних прізвиськ і замінюєте їх порожнім рядком "".
# 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)
Щоб видалити певний рядок файлу за його номером рядка :
Замініть ім'я файлу змінних та 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
синтаксисом.