Seite 1 von 1

Python Liste Textdatei zwei Zeilen hintereinander löschen

Verfasst: Donnerstag 2. März 2023, 21:37
von Kato1998
Hallo :D

Ich möchte ein Python Scrip schreiben in dem eine Textdatei eingelesen wird und dann, wenn in einer Zeile ein "up" vorkommt, wird die Zeile gelöscht wird und auch die nächste Zeile in der Liste

Hier ein Beispiel von meiner Text Datei
Name/0/2 is up, line protocol is up (verbunden)
Letzter input 00:01:33, output 00:00:06, abc abc abc
Name/0/2 is down, line protocol is down (getrennt)
Letzter input 20w0d, output 20w0d, abc abc abc
Name/0/3 is down, line protocol is down (getrennt)
Letzter input never, output never, abc abc abc
Name/0/4 is down, line protocol is down (getrennt)
Letzter input never, output never, abc abc abc
Name/0/5 is down, line protocol is down (getrennt)
Letzter input never, output never, abc abc abc
Name/0/6 is down, line protocol is down (getrennt)
Letzter input never, output never, abc abc abc
Name/0/7 is down, line protocol is down (getrennt)
Letzter input never, output never, abc abc abc
Name/0/8 is down, line protocol is down (getrennt)
Letzter input 18:30:15, output 18:29:38, abc abc abc
Name/0/9 is up, line protocol is up (verbunden)
Letzter input 1w2d, output 00:00:06, abc abc abc
Name/0/10 is up, line protocol is up (connected)
Letzter input 00:00:41, output 00:00:06, abc abc abc

Hier mein Programm:

Code: Alles auswählen

dat_auswertung = open(test.text)

for zeile in dat_auswertung:

    daten.append(zeile.split(" ")) 
    
dat_auswertung.close()


y=0
for x in daten:
    if "up" in daten[y][2]:
        print (y)
        print (daten[y][2])
        daten.pop(y)
        print (daten[y][2])
        daten.pop(y)
 y=y+1

Leider löscht es nicht alle Zeilen sondern nur manche :/

Re: Python Liste Textdatei zwei Zeilen hintereinander löschen

Verfasst: Donnerstag 2. März 2023, 22:13
von Dennis89
Hallo,

kannst du erklären, wieso das ' y=y+1' an der Stelle steht, an der es gerade ist und welche Auswirkung das auf das Programm hat. Und wieso zwei mal 'pop(y)' ?

Grüße
Dennis

Re: Python Liste Textdatei zwei Zeilen hintereinander löschen

Verfasst: Donnerstag 2. März 2023, 22:20
von Sirius3
Der Code ist nicht lauffähig, weil die Einrückungen nicht stimmen. `daten` wird nirgends definiert.
Dateien öffnet man immer innerhalb eines with-Statements und gibt das passende Encoding an.
`x` ist ein sehr schlechter Variablenname für die Teile einer Zeile.
Einen Index benutzt man nicht, vor allem nicht, wenn man ihn auch noch händisch zählt. Wenn man Zeilen aus einer Liste löscht, ändern sich auch die nachfolgenden Indices, was man aber auch nicht macht, weil man einfach eine neue Liste mit dem korrekten Inhalt erzeugt.

Code: Alles auswählen

with open(test.text, encoding="utf8") as zeilen:
    daten = []
    skip_next = False
    for zeile in zeilen:
        if skip_next:
            skip_next = False
        else:
            teile = zeile.split(" ")
            if "up" in teile[2]:
                skip_next = True
            else:
                daten.append(teile)
Die Frage ist aber, ob Du wirklich in jeder Zeile nach up suchen willst, da ja offensichtlich immer zwei Zeilen zusammengehören.

Re: Python Liste Textdatei zwei Zeilen hintereinander löschen

Verfasst: Donnerstag 2. März 2023, 22:34
von Axel-WAK
Ich wollte gerade das vorschlagen

Code: Alles auswählen

dat_auswertung = []
with open("test.txt", "r") as f:
    dat_auswertung = f.read().splitlines()
    
for i, zeile in reversed(list(enumerate(dat_auswertung))):
    if "up" in zeile:
        dat_auswertung.pop(i)
        dat_auswertung.pop(i)
        
print("\n".join(dat_auswertung))
Name/0/2 is down, line protocol is down (getrennt)
Letzter input 20w0d, output 20w0d, abc abc abc
Name/0/3 is down, line protocol is down (getrennt)
Letzter input never, output never, abc abc abc
Name/0/4 is down, line protocol is down (getrennt)
Letzter input never, output never, abc abc abc
Name/0/5 is down, line protocol is down (getrennt)
Letzter input never, output never, abc abc abc
Name/0/6 is down, line protocol is down (getrennt)
Letzter input never, output never, abc abc abc
Name/0/7 is down, line protocol is down (getrennt)
Letzter input never, output never, abc abc abc
Name/0/8 is down, line protocol is down (getrennt)
Letzter input 18:30:15, output 18:29:38, abc abc abc

Re: Python Liste Textdatei zwei Zeilen hintereinander löschen

Verfasst: Freitag 3. März 2023, 04:09
von snafu

Code: Alles auswählen

with open("test.log") as stream:
    while (line := stream.readline()):
        next_line = stream.readline()
        if "up" not in line.split():
            print(line, end="")
            print(next_line, end="")
Könnte man auch ohne readline() lösen, indem man diverse Iteratoren verschachtelt, aber ich fand es so einfach direkter. Das Ergebnis ist am Ende das selbe. Das Wesentliche hier ist, dass keine Listen benutzt werden. Damit schont man den Arbeitsspeicher und kann somit mühelos riesige Logfiles verarbeiten.

Aus Spaß an der Freude hier dennoch eine Variante unter Verwendung des externen ``more_itertools``-Moduls:

Code: Alles auswählen

from more_itertools import chunked, flatten

def filter_non_ups(stream):
    return flatten(
        pair for pair in chunked(stream, 2)
        if "up" not in pair[0].split()
    )

def main():
    with open("test.log") as stream:
        for line in filter_non_ups(stream):
            print(line, end="")

if __name__ == "__main__":
    main()
Beide verwendeten Funktionen des Moduls lassen sich auch relativ leicht mit den Möglichkeiten der Standardbibliothek nachbauen:

Code: Alles auswählen

from itertools import chain

def chunked(iterable, n):
    return zip(*[iter(iterable)] * n)

def filter_non_ups(stream):
    return chain.from_iterable(
        pair for pair in chunked(stream, 2)
        if "up" not in pair[0].split()
    )

def main():
    with open("test.log") as stream:
        for line in filter_non_ups(stream):
            print(line, end="")

if __name__ == "__main__":
    main()
Also zumindest für diesen Anwendungsfall. Im Detail verhält sich das more_itertools chunked() etwas anders, da es nicht auf zip() basiert.

Re: Python Liste Textdatei zwei Zeilen hintereinander löschen

Verfasst: Freitag 3. März 2023, 09:56
von kbr
Wie wäre es mit einem schönen Generator::

Code: Alles auswählen

def get_lines_without_up(fname):
    with open(fname) as fobj:
        for line in fobj:
            if "up" in line.split():
                next(fobj)
            else:
                yield line
                
for line in get_lines_without_up("lines.txt"):
    print(line.strip())

Re: Python Liste Textdatei zwei Zeilen hintereinander löschen

Verfasst: Freitag 3. März 2023, 17:29
von snafu
@kbr
``for`` und ``next()`` waren auch meine ersten Ideen. Am frühen Morgen war ich aber anscheinend zu doof für die Umsetzung. Hatte immer doppelte Zeilen in der Ausgabe, keine Ahnung warum. So wie dein Aufbau ist, klappt es natürlich. Das würde ich einem readline() auch vorziehen.

EDIT: Zur Sicherheit könnte man auch next(fobj, "") oder next(fobj, None) schreiben. Dann wird kein Fehler geworfen, falls die Datei aus irgendwelchen Gründen schon vor der letzten Folgezeile endet. Stattdessen gibt er den übergebenen Default-Wert zurück, den man dann natürlich ignorieren kann.