String in Substring

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
djwieli
User
Beiträge: 3
Registriert: Freitag 18. Januar 2019, 22:56

Hallo zusammen,

ich habe folgendes Problem:

Ich will von einem Ordner mit Logfiles bestimmte Logfiles in einen Unterordner kopieren, wenn in dem Unterordner bereits ein Ordner mit Datum vorhanden ist, und das Datum des Ordners im Logfilenamen enthalten ist. Ich probiere hier schon seit Stunden rum überhaupt mal einen Match zu bekommen, wenn es ein Ordner gibt, dessen Datum in einem Logfile vorkommt.

fnmatch will nicht, genauso wie string.contains(str) oder string in substring, etc.

Vielleicht hat jemand einen Tipp für mich.

Code: Alles auswählen

import os

for folder in os.listdir('/opt/fhem/log/archivedlogs/'):
    for datei in os.listdir('/opt/fhem/log/'):
        if folder in datei:
            print(datei, "-", folder)
Danke!
djwieli
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

ich sehe keine Frage und deine Ausführung ist schwer nachzuvollziehen.
Suchst du so etwas?

Code: Alles auswählen

>>> text = "Hallo du Test"
>>> "Luftballon" in text
False
>>> "du" in text
True
djwieli
User
Beiträge: 3
Registriert: Freitag 18. Januar 2019, 22:56

manchmal muss man einfach mal schlafen gehen ;-)

Code: Alles auswählen

#!/usr/bin/python3

import os
import time
import shutil

zielordner = "/opt/fhem/log/archivedlogs/"
logordner = "/opt/fhem/log/"

for folder in os.listdir(zielordner):
    #print(folder)
    #time.sleep(4)
    for datei in os.listdir(logordner):
        #print(datei)
        #time.sleep(1)
        if datei.__contains__(folder):
            print("verschiebe:", datei, zielordner + folder + "/")
            shutil.move(logordner + datei, zielordner + folder + "/")
            #print(datei, "-", folder)
            #time.sleep(2)
So läuft es jetzt bei mir. Ich hatte vorher keinen Match bekommen, da es keinen Ordner mit dem Datum gab. Herausgefunden habe ich das mit den Sleep steps und print Ausgaben. Nachdem ich den Ordner manuell angelegt hatte, lief das Script durch und die Dateien wurden verschoben.

VG
djwieli
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@djwieli: Die ”magischen” Methoden mit den doppelten Unterstrichen sollte man nur aufrufen wenn das unbedingt nötig ist. Die `__contains__()`-Methode ist für den ``in``-Operator gedacht, den man dann auch benutzen sollte.

Pfadteile setzt man mit `os.path.join()` zusammen, nicht mit ``+``. Ein abschliessendes Pfadtrennzeichen ist nicht nötig.

Das `folder` der einzige Englische Name ist, fällt irgendwie aus dem Rahmen. Ich würde ja komplett Englisch verwenden, aber auf jeden Fall konsequent nur *eine* Sprache. `folder` und `datei` sind auch inhaltlich falsch, weil es sich bei beiden nicht um einen Ordner oder eine Datei handelt, sondern jeweils um einen Ordner*namen* und einen Datei*namen*. Zum einen ist insbesondere `datei` irreführend, weil man bei dem Namen ein Objekt erwarten würde das `read()` oder `write()`-Methoden hat, eben ein Dateiobjekt, aber auch der Ausdruck ``folder in datei`` verwirrt extrem. Denn eigentlich sind ja Dateien in Ordnern und nicht umgekehrt, oder man denkt beim lesen `datei` ist ein zum lesen geöffnetes Dateiobjekt und der Ausdruck prüft ob eine Zeile mit dem Ordnernamen in der Datei enthalten ist. Eigendlich sollte das aber ``ordnername in dateiname`` heissen, was wesentlich besser und eindeutiger beschreibt was da passiert.

Man sollte sich nicht blind darauf verlassen das `folder` tatsächlich nur an Ordnernamen gebunden wird, sondern das explizit testen.

Der komplette Zielordnername wird zweimal exakt gleich zusammengesetzt. Wenn man testet ob das tatsächlich ein Verzeichnis ist, dann braucht man den sogar dreimal, man sollte den Namen aber nur einmal erstellen.

Beim äusseren `os.listdir()` würde sortieren sicherstellen, das bei Mehrdeutigkeiten vorhersehbarer ist, wo verschobene Dateien landen werden.

Das innere `os.listdir()` wird für jeden Durchlauf der äusseren Schleife aufgerufen. Das kann man sich sparen wenn man die Erstellung dieser Liste aus den Schleifen heraus zieht. Eventuell möchte man auch hier sicherstellen, dass es sich ausschliesslich um Dateinamen handelt und keine Verzeichnisse dabei sind?

Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python3
import os
import shutil

ARCHIVORDNERNAME = '/opt/fhem/log/archivedlogs'
LOGORDNERNAME = '/opt/fhem/log'


def main():
    #
    # TODO Maybe filter to just file names, without directories‽
    # 
    dateinamen = os.listdir(LOGORDNERNAME)
    
    for ordnername in sorted(os.listdir(ARCHIVORDNERNAME)):
        zielordnername = os.path(ARCHIVORDNERNAME, ordnername)
        if os.path.isdir(zielordnername):
            for dateiname in dateinamen:
                if ordnername in dateiname:
                    print(f'verschiebe {dateiname!r} nach {zielordnername!r}')
                    shutil.move(
                        os.path.join(LOGORDNERNAME, dateiname), zielordnername
                    )


if __name__ == '__main__':
    main()
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
djwieli
User
Beiträge: 3
Registriert: Freitag 18. Januar 2019, 22:56

@__blackjack__
Danke für deine Hinweise. Ich werde meinen Code dahinegehend noch mal "refactoren" :-)
Antworten