Seite 1 von 2

String in .txt suchen und davor alles löschen

Verfasst: Dienstag 3. November 2020, 12:53
von Eierlikörchen
Hallo zusammen,

ich bin Python-Neuling und habe folgendes vor:

Ich habe eine .txt mit mehreren Zeilen. Ich möchte jede Zeile durchsuchen und sobald die Textfolge "/$" gefunden
wird, soll alles davor in der Zeile gelöscht werden.

Ich habe schon viel gegoogelt, aber komme einfach nicht weiter :-/

Danke und viele Grüße

Simone

Re: String in .txt suchen und davor alles löschen

Verfasst: Dienstag 3. November 2020, 13:10
von einfachTobi

Re: String in .txt suchen und davor alles löschen

Verfasst: Dienstag 3. November 2020, 13:41
von DeaD_EyE

Code: Alles auswählen

def strip_text(input_file, output_file, pattern="/$"):
    pattern_len = len(pattern)
    with open(input_file, "rt", encoding="utf8") as fd_in, open(output_file, "wt", encoding="utf8") as fd_out:
        for line in fd_in:
            index = line.find(pattern)
            if index != -1:
                line = line[index + pattern_len:]
            fd_out.write(line)
  1. Datei zum lesen öffnen, Textmodus, utf8
  2. Datei zum schreiben neu erstellen, Textmodus, utf8
  3. Über die Zeilen der Eingabedatei iterieren (fd_in ist ein Iterator)
  4. Mit der Methode find das Muster finden. -1 == nicht gefunden
  5. Fall gefunden: Str an der Fundstelle + Länge des Musters abschneiden. Den Doppelpunkt beachten.
  6. Zeile in fd_out schreiben

Re: String in .txt suchen und davor alles löschen

Verfasst: Dienstag 3. November 2020, 14:26
von __blackjack__
Ich finde die Namen `input_file`/`fd_in` und `output_file`/`fd_out` nicht gut. Die Werte die `*_file` heissen sind gar keine Dateien sondern Datei*namen* und mit der kryptischen Abkürzung `fd` kann a) kein Anfänger etwas anfangen und ist b) in Python auch falsch, denn was in Unix & Co ein „file descriptor“ ist, also eine ganze Zahl die indirekt für eine Datei steht, ist in Python ein Dateiobjekt.

Re: String in .txt suchen und davor alles löschen

Verfasst: Dienstag 3. November 2020, 15:07
von Sirius3
Mit Index zu arbeiten, ist meist recht kryptisch. Python hat da Methoden, die auf einem höheren Niveau arbeiten.
Das magische -1 kommt auch eher aus einer low-level Programmiersprache.

Code: Alles auswählen

    head, sep, tail = line.partition(pattern)
    if sep:
        line = tail
oder das ganze in einer Zeile mit split:

Code: Alles auswählen

line = line.split(pattern, 1)[-1]

Re: String in .txt suchen und davor alles löschen

Verfasst: Dienstag 3. November 2020, 15:08
von Sirius3
@DeaD_EyE: Mit Index zu arbeiten, ist meist recht kryptisch. Python hat da Methoden, die auf einem höheren Niveau arbeiten.
Das magische -1 kommt auch eher aus einer low-level Programmiersprache.

Code: Alles auswählen

    head, sep, tail = line.partition(pattern)
    if sep:
        line = tail
oder das ganze in einer Zeile mit split:

Code: Alles auswählen

line = line.split(pattern, 1)[-1]

Re: String in .txt suchen und davor alles löschen

Verfasst: Mittwoch 4. November 2020, 11:49
von Eierlikörchen
Vielen Dank erstmal für Eure Antworten!! Als Anfängerin steige ich noch nicht ganz durch.
Ich habe mir jetzt mal was zusammengeschnipselt, was auch ganz gut funktioniert.
Ich starte mein "Test.py Input.txt" mit dem u.a. Code. Jetzt schneidet er für jede Zeile alles
vor "/$" ab, so wie ich es will. Er hängt die Output-Zeilen jetzt in der .txt aber unten dran. Wie schaffe ich
es, dass er den kompletten Inhalt der .txt löscht und nur die Output-Zeilen schreibt? Es soll alles
in der Input.txt stattfinden. Es soll keine zusätzliche Datei erstellt werden.

Lieben Dank für Eure Hilfe.
Simone

Code: Alles auswählen

import sys
input2 = sys.argv[1] 

with open(input2, 'r+') as textfile:

        lines = textfile.readlines()
        for l in lines:
                cut_string = l.split('/$')
                new_string = cut_string[1]
                textfile.write(new_string)             
 
textfile.close()

Re: String in .txt suchen und davor alles löschen

Verfasst: Mittwoch 4. November 2020, 12:10
von Sirius3
Eingerückt wird in Python immer mit 4 Leerzeichen pro Ebene, nicht 8.
Der Filemode 'r+' ist eigentlich nie sinnvoll. Wenn man gleichzeitig liest und schreibt, gehen Text-Dateien leicht kaputt.

Benutze sprechende Variabelnnamen. Was soll denn die 2 bei input2? l ist ein ganz schlechter Variablenname. cut_string ist eine Liste und kein String, daher sind Typen in Variablennamen selten sinnvoll. Wenn /$ mehrmals in einer Zeile vorkommen kann, dann ist der Code so nicht richtig.
Das close ist unnötig, da Du schon with benutzt.

Du mußt das in zwei Schritten machen, erst die Datei zum Lesen öffnen, dann die Daten modifizieren und dann die Datei neu zum Schreiben öffnen.
Normalerweise möchte man nicht, dass Input-Datei und Output-Datei den selben Namen haben, weil wenn was schief läuft sind die Daten weg.

Re: String in .txt suchen und davor alles löschen

Verfasst: Mittwoch 4. November 2020, 14:27
von DeaD_EyE
__blackjack__ hat geschrieben: Dienstag 3. November 2020, 14:26 Ich finde die Namen `input_file`/`fd_in` und `output_file`/`fd_out` nicht gut. Die Werte die `*_file` heissen sind gar keine Dateien sondern Datei*namen* und mit der kryptischen Abkürzung `fd` kann a) kein Anfänger etwas anfangen und ist b) in Python auch falsch, denn was in Unix & Co ein „file descriptor“ ist, also eine ganze Zahl die indirekt für eine Datei steht, ist in Python ein Dateiobjekt.
Ich habe mir das nicht ausgedacht, sondern diese Benennung einfach übernommen.
Wieso sollte ich jetzt andere Namen für etwas erfinden, dass bereits überall im Code ist und von jedem Anfänger in Tutorials gelesen wird?
Überall wird fd verwendet und in der Doku von Python an einer Stelle sogar nur f für ein fileobject.

Mit *_file gehe ich aber konform. Man könnte annehmen, dass es ein FileObject sein könnte, was es nicht ist.

@Sirius3 das mit partition gefällt mir am besten. Ich würde aber rpartition verwenden.

Code: Alles auswählen

def filter_pattern(text, pattern):
    return "".join(line.rpartition(pattern)[-1] for line in text.splitlines())
Hat den Vorteil, dass man die Bedingung nicht abfragen muss.

Re: String in .txt suchen und davor alles löschen

Verfasst: Mittwoch 4. November 2020, 15:33
von __blackjack__
@DeaD_EyE: Ich finde halt das man keine kryptischen Abkürzungen verwenden sollte. Die man einem Anfänger noch nicht mal richtig erklären kann, weil es ja auch nicht abgekürzt inhaltlich nicht passt. Auch wenn das irgendwo im Netz so gemacht wird. Da gibt es auch haufenweise Sternchen-Importe, ganz viel kaputten Socket-Code, und auch Code der ``global`` verwendet.

Re: String in .txt suchen und davor alles löschen

Verfasst: Mittwoch 4. November 2020, 16:41
von DeaD_EyE
Irgendwo? Überall wird fd verwendet. Wieso sollte ich jetzt für Anfänger davon abweichen?

Das ist genauso eine Konvention wie np für numpy. Es gibt kaum Code, wo numpy nicht np zugewiesen worden ist.

Das `global` und `from foo import *` schlecht sind, sollte in der PEP8 stehen und darüber braucht man nicht streiten.

Re: String in .txt suchen und davor alles löschen

Verfasst: Mittwoch 4. November 2020, 17:56
von __blackjack__
@DeaD_EyE: Ich sehe nicht das es überall verwendet wird und es ist inhaltlich halt trotzdem falsch.

Re: String in .txt suchen und davor alles löschen

Verfasst: Mittwoch 4. November 2020, 18:00
von Eierlikörchen
Ich komm nicht weiter :-/

Abgesehen von meinen "Anfänger-Bezeichnungen" für die Variablen bekomme ich es einfach nicht hin,
dass der Inhalt ersetzt und nicht hinten angefügt wird ... ich bin verzweifelt :-)

Hat jemand noch einen guten Tipp?

Danke und LG
Simone

Re: String in .txt suchen und davor alles löschen

Verfasst: Mittwoch 4. November 2020, 18:50
von __deets__
Du musst die Datei zweimal öffnen. Einmal mit r (ohne +) zum einlesen. Und wenn alles fertig ist l mit w zum Schreiben.

Re: String in .txt suchen und davor alles löschen

Verfasst: Mittwoch 4. November 2020, 19:06
von Eierlikörchen
Hallo deets,

wenn ich die Datei (r) schließe und anschließend mit (w) wieder öffne, dann schreibt
er nur die letzte Zeile die er gefunden hat mit "/$" in die Datei. Die anderen Zeilen darüber sind
weg. Was mache ich falsch?

Danke und Gruß
Simone

Code: Alles auswählen

import sys
input2 = sys.argv[1] 

with open(input2, 'r') as textfile:
   lines = textfile.readlines()
   for l in lines:
     
     cut_string = l.split('/$')
     new_string = cut_string[1]

textfile.close()     

with open(input2, 'w') as textfile2:
      textfile2.write(new_string)

Re: String in .txt suchen und davor alles löschen

Verfasst: Mittwoch 4. November 2020, 19:09
von Sirius3
@Eierlikörchen: Du mußt schon alle new_strings wieder in einer Liste sammeln.
Warum hast Du fast alles ignoriert, was ich geschrieben habe. Gute Variablennamen sind wichtig, damit DU den Code auch verstehst.

Re: String in .txt suchen und davor alles löschen

Verfasst: Mittwoch 4. November 2020, 19:22
von Eierlikörchen
@Sirius3: Ich glaube das Problem ist, dass ich gestern mich das erstmal überhaupt mit Python beschäftigt habe :-)
Daher will ich alles verstehen und nichts ignorieren. Aber als Anfängerin ist es schwierig "reinzukommen" ...

Re: String in .txt suchen und davor alles löschen

Verfasst: Donnerstag 5. November 2020, 13:32
von Eierlikörchen
Hat noch jemand noch einen Ansatz bzw. Code der mein Problem löst?

Grüße
Simone

Re: String in .txt suchen und davor alles löschen

Verfasst: Donnerstag 5. November 2020, 14:09
von __blackjack__
@Eierlikörchen: Bereits im dritten Beitrag vor zwei Tagen hat DeaD_EyE doch eine Lösung mit Erklärung was da passiert präsentiert‽ Bei der folgenden Diskussion unter uns alten Hasen ging es um die Namenswahl, nicht um den Code selbst. Warum bist *Du* denn mit *dem* Code nicht zufrieden?

Re: String in .txt suchen und davor alles löschen

Verfasst: Donnerstag 5. November 2020, 14:56
von Eierlikörchen
Der Code funktionierte bei mir nicht. Wo liegt der Fehler?

Wie müsste ich den Code verändern, damit die Änderungen direkt in der Datei und
nicht in eine neue Datei geschrieben werden?

Danke und Grüße

Code: Alles auswählen

input_file = "Input.txt"
output_file = "Output.txt"

def strip_text(input_file, output_file, pattern="/$"):
    
    pattern_len = len(pattern)
    
    with open(input_file, "rt", encoding="utf8") as fd_in, open(output_file, "wt", encoding="utf8") as fd_out:
        for line in fd_in:
            index = line.find(pattern)
            if index != -1:
                line = line[index + pattern_len:]
            fd_out.write(line)