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
txt dateien vergleichen
@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.
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.
Der kanonische Ansatz fuer so etwas ist der set-Datentyp:
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).
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()
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.
Und das io modul hast du verwendet um Strings an Stelle vonTextfiles zu verwenden?
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")
@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.
`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")
@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!
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!
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?
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?
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.
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.