[Gelöst] Python Datei öffnen, Zeichen finden, ersetzen und in Datei schreiben

  • Ich habe ein kleines Pythonscript geschrieben, welches mir eine Datei öffnet, Zeichen ersetzt und in eine neue Datei schreibt:

    Das funktioniert auch.

    Nun möchte ich aber, dass das Script aus z.B.:

    10.8.0.168/32

    192.168.34.8/24

    127.0.0.1/9

    so etwas macht:

    10.8.0

    192.168.34

    127.0.0

    Also den letzten ., die 1-3 Zahlen zwischen 0 und 255 und das / mit dem Rest.

    Mit welchem Werkzeug gehe ich da am besten ran ?

    Außerdem schaffe ich es nicht, eine Liste zu nehmen, welche WAS = ["/7", "[/8]", "/9" ] ... in einem Rutsch abarbeitet. :conf:

    :helpnew:

  • [Gelöst] Python Datei öffnen, Zeichen finden, ersetzen und in Datei schreiben? Schau mal ob du hier fündig wirst!

  • Moinsen,

    Du kannst zu einem mit <STRING>.conut(<Char>) prüfen, wie viele Punkte "." und ob ein Strich "/" in der Textzeile vorhanden ist. Dann lässt sich mit <STRING>.rsplit(<Char>, 1)[0] der betreffende Teil herauslösen.

    EDIT: Wenn der TEXT nur IP Adressen enthält lässt sich aus dem Read-Block auch wieder ein Write-Block machen.

    Damit müsste man diese Datei nicht zeilenweise einlesen.

    Franky

    Edited 2 times, last by Franky07 (December 6, 2023 at 8:55 AM).

  • Hallo,

    geht auch z.B. so:

    Python
    >>> eingabe = '10.8.0.168/32'
    >>> ip = eingabe.partition('/')
    >>> ip = eingabe.partition('/')[0]
    >>> ip
    '10.8.0.168'
    >>> ausgabe = '.'.join(ip.split('.')[0:3])
    >>> ausgabe
    '10.8.0'
    >>>

    Anstatt `split` kannst du natürlich auch rsplit und dann ohne join nehmen. `partition`würde dir erlauben, auch wenn nötig die Zahl nach dem / weiterzuverarbeiten.

    Gruß, noisefloor

  • hyle Das funktioniert, wenn ich txt = '192.168.123.0./24' setze.

    Wenn ich aber eine Textdatei öffne, in der steht

    Code
    In dieser Datei sollte 192.168.123.0/24 stehen.
    In der anderen Datei sollte 10.8.23.0/32 stehen.
    Auf keinen Fall sollte 127.0.0.1/7 drinstehen.

    dann bekomme ich nur 192.168.123

    noisefloor

    Python
    >>> eingabe = '10.8.0.168/32'
    >>> ip = eingabe.partition('/')
    >>> ip = eingabe.partition('/')[0]
    >>> ip
    '10.8.0.168'
    >>> ausgabe = '.'.join(ip.split('.')[0:3])
    >>> ausgabe
    '10.8.0'
    >>>

    Anstatt `split` kannst du natürlich auch rsplit und dann ohne join nehmen. `partition`würde dir erlauben, auch wenn nötig die Zahl nach dem / weiterzuverarbeiten.

    Ne, der / in der Zeile und alles dahinter kann/soll weg.

  • Bin schon bissl weiter:

    Ausgabe:

    Aber in der danach.txt steht nur:

    Code
    In dieser Datei sollte 192.168.123
    Auf keinen Fall sollte 127.0.0

    Also ignoriert er die 10.8.23.0/32 und die Zeilen, in denen danach noch Text kommt, ignoriert er komplett.

    Mal sehen, ob ich das noch hin bekomme.

  • Nur mal so als Tipp. Für solche Fragen wo man selber vielleicht gerade auf dem Schlauch steht, bietet sich immer ChatGPT an.
    Stelle ihm die Frage genau so wie uns und du bekommst den passenden Code dazu.

  • fred0815 Falls Dir der von mir vorgeschlagene Lösungsweg gruselig erscheint:

    Code
    for line in lines_from_file:
         m = re.search(r".*\s([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})\.[0-9]{1,3}/[0-9]{1,2}\s", line)
         if m:
             print(m.groups()[0])

    Regular Expressions sind einfach oft so... 8)

    Hier ein kurzer Erklärungsversuch:

    Diese regex ist mit Sicherheit nicht perfekt oder optimal, aber immerhin eine Möglichkeit. Je nach echtem Dateninhalt muss evtl. noch angepasst werden.

    Wenn o.g. Expression passt (matched), entsteht ein Match-Objekt (hier in m = ) und mit

    m.groups()[0] wird auf die erste Gruppe im Treffer zugegriffen, also hier die Teil-IP-Adresse.

  • @AlexanderX Nee, da kommt zum überwiegenden Teil kein passender Code heraus. Das funktioniert bei Standardhausaufgaben und Minimalbeispielen die 100-tausendfach so ähnlich im Netz stehen. Nicht bei realen, individuellen Aufgaben. Da muss man so weit programmieren können um die Antworten bewerten und korrigieren zu können, dass man es einfach selber hätte schreiben können. Oder die Leute die das nicht können, schlagen dann mit so kaputtem Zeugs in Foren auf und wollen das von anderen geradegebogen bekommen.

    Franky07 Kannst Du bitte aufhören Bilder von Quelltext zu posten?

    fred0815 ``for zeile in datei:`` iteriert schon über die Datei. Wenn Du *in* der Schleife dann noch ein `readline()` machst, dann ”klaust” Du der Schleife jede zweite Zeile die nicht mehr zu `zeile` werden kann.

    Das mit dem Ausgabedatei jedes mal mit "a" öffnen ist nicht gut. Neben dem Aufwand, erweitert das auch bei jedem Lauf diese Datei, statt mit einer leeren Datei anzufangen.

    Kann eigentlich nur eine IP pro Zeile auftreten? Und *tritt* in *jeder* Zeile auch eine IP auf?

    “It is easier to optimize correct code than to correct optimized code.” — Bill Harlan

  • Kann eigentlich nur eine IP pro Zeile auftreten? Und *tritt* in *jeder* Zeile auch eine IP auf?

    Pro Zeile kommt maximal nur eine IP vor, aber nicht in jeder Zeile steht eine.

    Aber danke, mit den Vorschlägen komme ich schon viel weiter, den Rest bekomme ich bestimmt hin.

    :bravo2: :danke_ATDE:

    P.S.

    __blackjack__

    Bei deinem Script kommt die Meldung:

    module 're' has no attribute 'compiler'

    Wenn ich versuche:

    Python
    #!/usr/bin/python3
    
    from re import compiler
    
    IP_RE = compiler("\d+\.\d+\.\d+)\.\d+/\d+")
    ...

    kommt ImportError: cannot import name 'compiler' from 're' (/usr/lib/python3.9/re.py)

  • Muss die Klammer nicht auch irgendwo hin ?

    Ja klar, so wie in #16 und #18:

    Code
    IP_RE = compile(r"(\d+\.\d+\.\d+)\.\d+/\d+")

    Das r gehört in die Klammer, direkt vor die Anführungszeichen und bedeutet "raw".

    Siehe https://docs.python.org/3/library/re.html

    Quote

    The solution is to use Python’s raw string notation for regular expression patterns; backslashes are not handled in any special way in a string literal prefixed with 'r'. So r"\n" is a two-character string containing '\' and 'n', while "\n" is a one-character string containing a newline. Usually patterns will be expressed in Python code using this raw string notation.

    Edited once, last by simonz: Fehlende Klammer ergänzt. (December 7, 2023 at 10:08 AM).

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!