txt dateien vergleichen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Samka
User
Beiträge: 1
Registriert: Montag 26. Oktober 2020, 21:39

Hallo,

ich würde gerne 2 txt Dateien mit einander vergleichen und neue Zeilen in einer neuen txt Datei abspeichern. Danach soll die erste txt Datei alles neue aus der zweiten txt Datei abspeichern.
Bin dankbar für jede Hilfe oder jeden Ansatz.

Mit freundlichen Grüßen,.
Samka
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@Samka,

Also als Ansatz:
Wenn es um Zeilenvergleich geht, würde ich beide Dateien in eine eigene Liste auslesen und dann für jedes Element der zweiten Liste prüfen ob es irgendwo in der ersten Liste vorkommt.
Falls nicht, ist es neu und wird in die neue Datei gespeichert.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Der kanonische Ansatz fuer so etwas ist der set-Datentyp:

Code: Alles auswählen

import io

FIRST_FILE = """a
b
c
d
e
q
"""

SECOND_FILE = """a
b
x
c
d
y
e
"""


def main():
    with io.StringIO(FIRST_FILE) as first, io.StringIO(SECOND_FILE) as second:
        first_entries = set(line.strip() for line in first.readlines())
        second_entries = set(line.strip() for line in second.readlines())

        print(second_entries - first_entries)
        print(second_entries ^ first_entries)


if __name__ == '__main__':
    main()
Dabei gibt es auch noch eine Reihe anderer Operationen, um zwei Mengen miteinander zu vergleichen. Mein Beispiel berechnet, was in second ist, das nicht in first steckt. Aber es gibt auch Eintraege in first, die nicht is second sind. Die Gesamtmenge der entweder nicht in der einen oder nicht in der anderen Datei zeigt uns der ^-Operator (symetric_difference).
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

Ja, der Ansatz mit 'set' ist wesentlich eleganter durch die möglichen Set-Operationen

Der Vollständigkeit halber noch das vom TO gewünschte Zurückschreiben in eine neue Datei. Und Entfernen der Leerstrings.

Code: Alles auswählen

with open("file1.txt", "r") as file1, open("file2.txt", "r") as file2, open("file_new.txt", "w") as file_new:
    first_entries = set(line.strip() for line in file1.readlines())
    second_entries = set(line.strip() for line in file2.readlines())

    new_entries = [entry for entry in second_entries - first_entries if entry]
    
    for line in new_entries:
        file_new.write(f"{line}\n")
Und das io modul hast du verwendet um Strings an Stelle vonTextfiles zu verwenden?
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

@rogerb: Lesen und Schreiben sind zwei getrennte Operationen, die gehören nicht in den selben with-Block. Genauso könnte man die zwei Read in zwei Blöcke packen.
`readlines` ist überflüssig, weil man direkt über die Zeilen einer Datei iterieren kann.

Code: Alles auswählen

with open("file1.txt", "r") as file:
    first_entries = set(line.strip() for line in file)
with open("file2.txt", "r") as file:
    second_entries = set(line.strip() for line in file)

new_entries = [entry for entry in second_entries - first_entries if entry]

with open("file_new.txt", "w") as file_new:    
    for line in new_entries:
        file_new.write(f"{line}\n")
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@Sirius3,

Mit Python 3.1 kam die Möglichkeit mehrere Context-Manager in einem with-Block zu öffnen, neu hinzu.
Es geht ja hier nicht darum, was in einer Zeile steht (außer dass sie vielleicht zu lang wird) sondern um das was im Hintergrund passiert.

Also das man es nicht machen muss, ... klar. Aber dass man es nicht machen sollte, ...?
Kannst du das mal bitte ein wenig präzisieren?

... `readlines` ist überflüssig ... - Ja!
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

Der Mensch kann nur drei Dinge gleichzeitig verarbeiten. Merke Dir drei Zahlen, 342, 782 und 123. Wird etwas zu komplex, muß man immer hin und her springen. Du wirst jetzt sagen, dass Du Dir natürlich viel mehr merken kannst, aber dann bist Du nur im hin und her springen sehr effizient.
Wie viel schneller kannst Du einen Code lesen, wenn jede Zeile so weniger komplex ist.
Wenn ich in Zeile 1 noch keine Datei schreiben muß, sondern erst in Zeile 5, dann muß ich in Zeile 1 noch nicht die Datei öffnen. Was war die zweite Zahl? Und hast Du nochmal an den Anfang geschaut?
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

Ich kann mir nichts merken, deswegen programmiere ich ja...
Okay, ja, Lesbarkeit ist ein wichtiger Aspekt.
Benutzeravatar
snafu
User
Beiträge: 6871
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Wobei line.strip() nicht immer eine gute Idee ist, weil das mehr abschneiden könnte als erwartet. Man denke da zB an eingerückten Programmcode. Zur Sicherheit also besser rstrip() benutzen, damit nur Whitespace am Zeilenende entfernt wird. Oder die Zeile einfach so belassen wie sie ist, denn das Newline-Zeichen braucht man beim Reinschreiben ja eh wieder.

Weiterhin muss man bedenken, dass Sets die Reihenfolge der Zeilen durcheinander bringen können. Die ist nämlich nicht garantiert. Kann ja sein, dass das wichtig ist. Dann müsste man es ohne Sets lösen.
Antworten