Antworten:
Öffnen Sie zuerst die Datei und holen Sie alle Ihre Zeilen aus der Datei. Öffnen Sie dann die Datei im Schreibmodus erneut und schreiben Sie Ihre Zeilen zurück, mit Ausnahme der Zeile, die Sie löschen möchten:
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)
Sie müssen strip("\n")
das Newline-Zeichen im Vergleich verwenden, denn wenn Ihre Datei nicht mit einem Newline-Zeichen endet, wird das allerletzte line
auch nicht.
Lösung für dieses Problem mit nur einem einzigen offenen:
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()
Diese Lösung öffnet die Datei im R / W-Modus ("r +") und verwendet die Suche, um den f-Zeiger zurückzusetzen und dann abzuschneiden, um alles nach dem letzten Schreibvorgang zu entfernen.
for
Schleife erhalten, erhalten Sie eine teilweise überschriebene Datei mit doppelten Zeilen oder einer halb abgeschnittenen Zeile. Vielleicht möchten Sie stattdessen f.truncate()
gleich danach f.seek(0)
. Auf diese Weise erhalten Sie bei einer Fehlermeldung nur eine unvollständige Datei. Die eigentliche Lösung (wenn Sie über ausreichend Speicherplatz verfügen) besteht darin, in eine temporäre Datei auszugeben und diese dann zu verwenden os.replace()
oder pathlib.Path(temp_filename).replace(original_filename)
mit dem Original auszutauschen, nachdem alles erfolgreich war.
i.strip('\n') != "line you want to remove..."
wie in der akzeptierten Antwort erwähnt, das würde mein Problem perfekt lösen. Weil i
ich einfach nichts für mich getan habe
Die beste und schnellste Option, anstatt alles in einer Liste zu speichern und die Datei erneut zu öffnen, um sie zu schreiben, ist meiner Meinung nach, die Datei an anderer Stelle neu zu schreiben.
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)
Das ist es! In einer Schleife und nur einer können Sie dasselbe tun. Es wird viel schneller sein.
(output.write(line) for line in input if line!="nickname_to_delete"+"\n")
subprocess.call(['mv', 'newfile.txt', 'yourfile.txt'])
os.replace
(neu in Python v 3.3) ist plattformübergreifender als ein Systemaufruf mv
.
Dies ist eine "Abzweigung" aus der Antwort von @Lother (die meiner Meinung nach als die richtige Antwort angesehen werden sollte).
Für eine Datei wie diese:
$ cat file.txt
1: october rust
2: november rain
3: december snow
Diese Gabel aus Lothers Lösung funktioniert einwandfrei:
#!/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()
Verbesserungen:
with open
, die die Verwendung von verwerfen f.close()
if/else
für die Bewertung, ob die Zeichenfolge in der aktuellen Zeile nicht vorhanden istDas Problem beim Lesen von Zeilen im ersten Durchgang und beim Vornehmen von Änderungen (Löschen bestimmter Zeilen) im zweiten Durchgang besteht darin, dass Ihnen bei großen Dateigrößen der Arbeitsspeicher ausgeht. Stattdessen ist es besser, die Zeilen einzeln zu lesen und in eine separate Datei zu schreiben, um die nicht benötigten zu entfernen. Ich habe diesen Ansatz mit Dateien mit einer Größe von 12 bis 50 GB ausgeführt, und die RAM-Auslastung bleibt nahezu konstant. Nur CPU-Zyklen zeigen die laufende Verarbeitung an.
Ich mochte den Dateieingabeansatz, wie in dieser Antwort erläutert: Löschen einer Zeile aus einer Textdatei (Python)
Angenommen, ich habe eine Datei mit leeren Zeilen und möchte leere Zeilen entfernen. So habe ich sie gelöst:
import fileinput
import sys
for line_number, line in enumerate(fileinput.input('file1.txt', inplace=1)):
if len(line) > 1:
sys.stdout.write(line)
Hinweis: Die Leerzeilen in meinem Fall hatten die Länge 1
Wenn Sie Linux verwenden, können Sie den folgenden Ansatz ausprobieren.
Angenommen, Sie haben eine Textdatei mit dem Namen animal.txt
:
$ cat animal.txt
dog
pig
cat
monkey
elephant
Löschen Sie die erste Zeile:
>>> import subprocess
>>> subprocess.call(['sed','-i','/.*dog.*/d','animal.txt'])
dann
$ cat animal.txt
pig
cat
monkey
elephant
Ich denke, wenn Sie die Datei in eine Liste einlesen, können Sie die Liste durchlaufen, um nach dem Spitznamen zu suchen, den Sie entfernen möchten. Sie können dies sehr effizient tun, ohne zusätzliche Dateien zu erstellen, aber Sie müssen das Ergebnis in die Quelldatei zurückschreiben.
So könnte ich das machen:
import, os, csv # and other imports you need
nicknames_to_delete = ['Nick', 'Stephen', 'Mark']
Ich gehe davon aus, nicknames.csv
enthält Daten wie:
Nick
Maria
James
Chris
Mario
Stephen
Isabella
Ahmed
Julia
Mark
...
Laden Sie dann die Datei in die Liste:
nicknames = None
with open("nicknames.csv") as sourceFile:
nicknames = sourceFile.read().splitlines()
Als nächstes iterieren Sie zur Liste, um Ihren zu löschenden Eingaben zu entsprechen:
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
Zuletzt schreiben Sie das Ergebnis zurück in die Datei:
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()
Im Allgemeinen können Sie nicht; Sie müssen die gesamte Datei erneut schreiben (zumindest vom Zeitpunkt der Änderung bis zum Ende).
In bestimmten Fällen können Sie es besser machen -
Wenn alle Ihre Datenelemente dieselbe Länge und keine bestimmte Reihenfolge haben und Sie den Versatz des Elements kennen, das Sie entfernen möchten, können Sie das letzte Element über das zu löschende Element kopieren und die Datei vor dem letzten Element abschneiden ;;
Oder Sie können den Datenblock einfach mit dem Wert "Dies sind fehlerhafte Daten, überspringen Sie ihn" überschreiben oder das Flag "Dieses Element wurde gelöscht" in Ihren gespeicherten Datenelementen beibehalten, sodass Sie es als gelöscht markieren können, ohne die Datei anderweitig zu ändern.
Dies ist wahrscheinlich ein Overkill für kurze Dokumente (alles unter 100 KB?).
Wahrscheinlich haben Sie bereits eine richtige Antwort erhalten, aber hier ist meine. Anstatt eine Liste zum Sammeln ungefilterter Daten zu verwenden (welche readlines()
Methode funktioniert), verwende ich zwei Dateien. Eine dient zum Halten von Hauptdaten und die zweite zum Filtern der Daten, wenn Sie eine bestimmte Zeichenfolge löschen. Hier ist ein Code:
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()
Ich hoffe, Sie finden das nützlich! :) :)
Speichern Sie die Dateizeilen in einer Liste, entfernen Sie dann die zu löschende Zeile aus der Liste und schreiben Sie die verbleibenden Zeilen in eine neue Datei
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)
Hier ist eine andere Methode, um eine / mehrere Zeile (n) aus einer Datei zu entfernen:
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()
Sie können die
re
Bibliothek verwenden
Angenommen, Sie können Ihre vollständige txt-Datei laden. Anschließend definieren Sie eine Liste unerwünschter Spitznamen und ersetzen diese durch eine leere Zeichenfolge "".
# 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)
So löschen Sie eine bestimmte Zeile einer Datei anhand ihrer Zeilennummer :
Ersetzen Sie die Variablen Dateiname und line_to_delete durch den Namen Ihrer Datei und die Zeilennummer, die Sie löschen möchten.
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))
Beispiel Ausgabe :
Deleted line: 3
for nb, line in enumerate(f.readlines())
Nehmen Sie den Inhalt der Datei und teilen Sie ihn durch Zeilenumbruch in ein Tupel auf. Greifen Sie dann auf die Zeilennummer Ihres Tupels zu, verbinden Sie Ihr Ergebnistupel und überschreiben Sie die Datei.
tuple(f.read().split('\n'))
? (2) "Zugriff auf die Zeilennummer Ihres Tupels" und "Join your result tuple" klingen ziemlich mysteriös; Der tatsächliche Python-Code ist möglicherweise verständlicher.
fileinput
wie von @ jf-sebastian hier beschrieben . Es scheint Ihnen zu ermöglichen, Zeile für Zeile über eine temporäre Datei mit einer einfachenfor
Syntax zu arbeiten.