web-dev-qa-db-ger.com

verwenden Sie Python zum Löschen einer bestimmten Zeile in einer Datei

Nehmen wir an, ich habe eine Textdatei mit Spitznamen. Wie kann ich einen bestimmten Spitznamen mit Python aus dieser Datei löschen?

103
SourD

Angenommen, Ihre Datei hat das Format eines Kurznamens pro Zeile. Verwenden Sie dies.

Öffnen Sie zuerst die Datei:

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

Als nächstes erhalten Sie alle Zeilen aus der Datei:

lines = f.readlines()

Nun können Sie die Datei schließen:

f.close()

Und wieder im Schreibmodus öffnen:

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

Schreiben Sie dann Ihre Zeilen zurück, mit Ausnahme der Zeile, die Sie löschen möchten. Möglicherweise möchten Sie den "\n" in die Zeile ändern, in der Ihre Datei endet.

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

Schließen Sie die Datei am Ende erneut.

f.close()
150
houbysoft

Lösung für dieses Problem mit nur einer offenen:

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()

Diese Lösung öffnet die Datei im Modus "r/w" ("r +") und setzt den F-Zeiger mithilfe von search zurück, kürzt sie dann ab und entfernt nach dem letzten Schreibvorgang alles.

76
Lother

Die beste und schnellste Möglichkeit, anstatt alles in einer Liste zu speichern und die Datei erneut zu öffnen, um sie zu schreiben, besteht meiner Meinung nach darin, 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!="nickname_to_delete"+"\n":
                output.write(line)

Das ist es! In einer und nur einer Schleife können Sie dasselbe tun. Es wird viel schneller sein.

18
Barnabe

Dies ist eine "Abzweigung" von @Lother (die meiner Meinung nach als die richtige Antwort betrachtet werden sollte).


Für eine Datei wie diese:

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

Diese Gabel von Lother's Lösung funktioniert gut:

#!/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, der die Verwendung von f.close() verwirft
  • klarer if/else für die Bewertung, ob in der aktuellen Zeile kein String vorhanden ist
16
ivanleoncz

Das Problem beim Lesen von Zeilen im ersten Durchlauf und beim Durchführen von Änderungen (Löschen bestimmter Zeilen) im zweiten Durchlauf besteht darin, dass bei einer sehr großen Dateigröße der Arbeitsspeicher knapp wird. Besser ist es, Zeilen nacheinander zu lesen und in eine separate Datei zu schreiben, wodurch die nicht benötigten Zeilen entfernt werden. Ich habe diesen Ansatz mit Dateien mit einer Größe von 12 bis 50 GB ausgeführt, und die Verwendung von RAM bleibt nahezu konstant. Nur die CPU-Zyklen zeigen die Verarbeitung an.

3
Kingz

Wenn Sie Linux verwenden, können Sie den folgenden Ansatz versuchen.
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
3
Ren

Ich denke, wenn Sie die Datei in eine Liste einlesen, dann können Sie die Liste durchlaufen, um nach dem Spitznamen zu suchen, den Sie loswerden möchten. Sie können dies sehr effizient tun, ohne zusätzliche Dateien erstellen zu müssen. Das Ergebnis muss jedoch in die Quelldatei zurückgeschrieben werden.

So könnte ich das machen:

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

Ich gehe davon aus, dass nicknames.csv Daten enthält 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 wiederholen Sie die Liste mit den zu löschenden Eingaben:

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

Zum Schluss schreibe 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()
2
A Malik

Keine gute Lösung, wenn Sie eine ganze Datei in den Speicher legen. Ich weiß, heutzutage hat jeder eine Menge Speicher, aber überlegen Sie, ob die Datei mehrere GB Protokolle enthält.

Kopieren Sie es zeilenweise in eine neue Datei, als die erste oder ähnliches zu löschen

2
user3063349

Der in dieser Antwort erläuterte Ansatz der Dateieinstellung hat mir gefallen: Löschen einer Zeile aus einer Textdatei (Python)

Angenommen, ich habe zum Beispiel eine Datei, die leere Zeilen enthält, und ich 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 leeren Zeilen in meinem Fall hatten Länge 1

1
Deep

Im Allgemeinen können Sie nicht; Sie müssen die gesamte Datei erneut schreiben (zumindest vom Änderungspunkt bis zum Ende).

In bestimmten Fällen können Sie das noch besser machen -

wenn alle Ihre Datenelemente dieselbe Länge und keine bestimmte Reihenfolge haben und Sie den Versatz des Elements kennen, das Sie loswerden 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 schlechte Daten, überspringen" oder "In diesem Element wurde gelöscht" in Ihren gespeicherten Datenelementen überschreiben, sodass Sie ihn als gelöscht markieren können, ohne die Datei anderweitig zu ändern.

Bei kurzen Dokumenten (etwas unter 100 KB?) Ist dies wahrscheinlich zu viel.

1
Hugh Bothwell

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)
0

hier ist eine andere Methode, um eine/einige Zeilen 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()
0
ungalcrys

Wahrscheinlich hast du schon eine richtige Antwort bekommen, aber hier ist meins . Statt eine Liste zu verwenden, um ungefilterte Daten zu sammeln (was die readlines()-Methode tut), 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! :)

0
andrii1986

Ich mag diese Methode mit Fileinput und der Inplace-Methode:

import fileinput
for line in fileinput.input(fname, inplace =1):
    line = line.strip()
    if not 'UnwantedWord' in line:
        print(line)

Es ist ein bisschen weniger wortreich als die anderen Antworten und ist schnell genug für

0
Ru887321

Sie können die Bibliothek re verwenden

Vorausgesetzt, Sie können Ihre vollständige txt-Datei laden. Anschließend definieren Sie eine Liste unerwünschter Kurznamen 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)
0
mrk