Dateien gemäß Inhalt verschieben

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
YannVDC
User
Beiträge: 1
Registriert: Montag 6. März 2017, 15:11

Hallo!

Ich habe mit einem Kollegen zusammen für interne Zwecke ein kleines Script in Python geschrieben, welches leider noch einen Fehler hat. Ich muss dazu sagen, das wir beide komplette Python-Neulinge sind. Der Grund warum wir nun diese Sprache gewählt haben ist der, dass auf der Plattform schon Python verwendet wird und es sich so anbot. Ausserdem wollten wir beide auch mal was in Python machen ;)

Nun, was macht das Script: Wir haben einen Ordner mit diversen Textdateien (bzw. XML) darin. Das Script soll dieses Verzeichnis durchkämmen und jede Datei nach bestimmten Inhalten. Sobald der gewünschte Inhalt gefunden wird (die Datei wird Zeile für Zeile durchgelesen), soll diese geschlossen und verschoben werden.
Das klappt auch ohne Probleme. Problematisch wird es bei den Dateien, die durch diesen Raster fallen. Diese sollten dann später geschlossen und verschoben werden. Bzw. habe ich versucht es mit einer Hilfsvariable zu lösen, die dauerhaft auf 0 ist (h = 0), nur bei positivem Durchlauf wird sie auf 1 gesetzt.
Unser Problem ist nun, dass die "fehlerhafte" Datei (sprich jene, in der nichts gefunden wurde) zwar im Zielordner auftaucht, aber nur als Kopie. Sie bleibt auch immer noch im Quellverzeichnis zurück.

Code: Alles auswählen

#Module importieren
import logging, shutil, glob, os, sys, time



#globale Variablen definieren
stamm_vz = 'C:\\Dev\\Import\\Stammdaten\\'
st_in = stamm_vz + 'In\\*.xml'
st_in_me = stamm_vz + 'In_me'
log_file = stamm_vz + 'Log_me\\multi_energy.log'
st_in_strom = stamm_vz + 'In_strom'



#Funktionen definieren
#Funktion Logging
def set_log():
    logging.basicConfig(filename=log_file, level=logging.INFO, format='%(asctime)s - %(levelname)s: %(message)s')



#Logdatei prüfen
def logdatei():
    #Loggrösse prüfen
    if os.path.isfile(log_file):
        logsize  = os.path.getsize(log_file)
    else:
        logsize = 1
    if logsize > 2000000:
        try:
            #Datei löschen wenn grösser als 2 MB
            shutil.copy(log_file, stamm_vz + 'Log_me\\archive\\multi_energy.log')
            os.remove(log_file)
            #Logdatei neu initialisieren
            set_log()
            logging.info('---------------------------------------------------------------------'.format(log_file))
            logging.info('Analyse Stammdaten Multi Energie wird gestartet')
            logging.info('Logformat wurde gesetzt und Logging wird begonnen')
            logging.info('Logdatei war > als 2MB und wurde gelöscht')
        except:
            logging.info('Fehler - Logdatei konnte nicht gelöscht werden - Bitte überprüfen')
    else:
        set_log()
        logging.info('---------------------------------------------------------------------'.format(log_file))
        logging.info('Analyse Stammdaten Multi Energie wird gestartet')
        logging.info('Logformat wurde gesetzt und Logging wird begonnen')
        logging.info('Logdatei < 2 MB - Logdatei nicht gelöscht')



#Funktion Scan Stmmdatenverzeichnis
def scan_stvz():
    #scan ob xml-Dateien vorhanden
    if glob.glob(st_in):
        #Datei öffnen
        for i in glob.glob(st_in):
            try:
                file = open(i, 'r')
                l = 0
                for line in file:
                    #scan nach Gas oder Wasser MP
                    l = l + 1
                    if '<meteringcode>CH8' in line or '<meteringcode>CH7' in line:
                        l = str(l)
                        logging.info('Datei ' + os.path.basename(i) + ' Zeile ' + l + ' enthält Gas / Wasser Messpunkt' + line.rstrip())
                        file.close()
                        h = 1
                        try:
                            #Datei verschieben
                            #print(os.path.basename(i) + line.rstrip())
                            shutil.move(i, st_in_me)
                            logging.info('Stammdatenfile ' + os.path.basename(i) + ' erfolgreich verschoben')
                            break
                        except:
                            logging.info('Fehler - Stammdatendatei kann nicht verschoben werden')
                    else:
                        h = 0
                # Der Fehler tritt hier auf. 
                if h == 0:
                    print(i)
                    file.close
                    #shutil.move(i, st_in_strom)
                    #logging.info(os.path.basename(i) + ' Stammdatendatei enthält keine Wasser / Gas Messpunkte -> für Stromimport verschoben')
                    #print(os.path.basename(i))
                    try:
                        #Datei verschieben
                        #print(os.path.basename(i) + line.rstrip())
                        shutil.move(i, st_in_strom)
                        logging.info(os.path.basename(i) + ' Stammdatendatei enthält keine Wasser / Gas Messpunkte -> für Stromimport verschoben')
                        break
                    except:
                        logging.info('Fehler - Stammdatendatei kann nicht verschoben werden -> '+st_in_strom)

            except:
                logging.info('Fehler - Stammdatendatei kann nicht geöffnet werden')


    else:
        logging.info('Keine Stammdatendateien vorhanden')



def main():
    #Logging
    logdatei()

    #Scan Stmmdatenverzeichnis
    scan_stvz()

    #Programm beenden
    logging.info('Stammdaten-Analyse erfolgreich ausgeführt')
    sys.exit()

main()
Wir vermuten beide, dass das file.close für diese Dateien an falscher Stelle stehen, blicken aber da nicht ganz durch :-( Kann uns hier jemand helfen?

Beste Grüsse
Yann
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@YannVDC: XML-Dateien sind keine Text-Dateien, man sollte sie deshalb auch nicht wie welche behandeln. Kryptische Abkürzungen vermeiden. Du weißt selbst in zwei Tagen nicht mehr, was mit st_in_me gemeint war. Pfade setzt man mit os.path.join und nicht mit + zusammen. Und wenn man Dateien schließen will, sollte man close auch **aufrufen** (Zeile 122). i ist ein ganz schlechter Variablenname für einen Dateinamen. Und außerdem unterscheidet er sich visuell kaum von l was auch ein ganz schlechter Variablenname für eine Zeilennummer ist. Man würde wohl eine Funktion schreiben, die zurückgibt, ob die Datei das gesuchte enthält und je nachdem in das eine oder andere Verzeichnis verschieben. Dann spart man sich dieses verschachtelte close (weil man einfach das with-Statement benutzen kann) und den doppelten Verschiebecode.

Ungetestet:

Code: Alles auswählen

import glob
import shutil
import logging
import xml.etree.ElementTree as et

def contains_CHx(filename):
    root = et.parse(filename)
    metering = root.findtext(".//meteringcode")
    return metering and ("CH8" in metering or "CH7" in metering)

def scan_stammdatenverzeichnis(st_in):
    for filename in glob.glob(st_in):
        if contains_CHx(filename):
            logging.info('Datei %s enthält Gas / Wasser Messpunkt', filename)
            target = st_in_me
        else:
            logging.info('Datei %s enthält keinen Gas / Wasser Messpunkt', filename)
            target = st_in_strom
        shutil.move(filename, target)
Antworten