Dateien und Ordner älter als 7 Tage löschen.

  • Hallo

    Ich habe angefangen ein Script zu schreiben, das alle Dateien in einem Ordner und in dessen Unterordnern löschen soll, die älter als 7 Tage sind.
    Das funktioniert auch so weit ganz gut, allerdings lässt das Script leere Ordner zurück und bricht komplett ab, wenn ein Ordner bereits leer ist.

    Wie kann ich erreichen, das das Skript bei leeren Ordnern nicht abbricht, sondern nur die aktuelle Funktion verlässt ?

    Wie kann ich meine Löschfunktion so umfunktionieren, das sie leere Ordner mit entfernt ? Ich habe die Funktion kopiert und anders benannt (deleteemtpydirectories), aber ich weiß nicht, ob eine zweite Funktion dafür überhaupt nötig ist.

    Spoiler anzeigen
    [autoit][/autoit] [autoit][/autoit] [autoit]

    Func schaltjahr ($jahr)
    If (Mod($jahr, 4) = 0) Then
    If (Mod($jahr, 100) = 0) Then
    If (Mod($jahr, 400) = 0) Then
    Return 1
    Else
    Return 0
    EndIf
    Else
    Return 1
    EndIf
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func tagedesmonats ($month, $jahr)
    Switch $month
    Case 1
    Return 31
    Case 2
    If schaltjahr($jahr) Then
    Return 29
    EndIf
    Return 28
    Case 3
    Return 31
    Case 4
    Return 30
    Case 5
    Return 31
    Case 6
    Return 30
    Case 7
    Return 31
    Case 8
    Return 31
    Case 9
    Return 30
    Case 10
    Return 31
    Case 11
    Return 30
    Case 12
    Return 31
    EndSwitch
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func deleteold ($filename, $days)

    $zeit = FileGetTime ( $filename )
    If ($zeit[0] = @YEAR) Then
    ;Datei ist aus diesem Jahr
    If $zeit[1] = @MON Then
    ;Datei ist aus diesem Monat
    If $zeit[2] = @MDAY Then
    ;Datei ist von Heute
    ElseIf (@MDAY - $zeit[2]) >= $days Then
    ;Datei ist älter/gleichalt als sieben Tage, also löschen
    Return 1
    EndIf
    ElseIf $zeit[1] < @MON Then
    ;Monatszahl in Datei ist kleiner als aktuelle Monatszahl
    ;Prüfen ob Datei von letztem Monat ist
    If ((@MON - $zeit[1]) = 1) Then
    $alterintagen = (tagedesmonats($zeit[1],@YEAR) - $zeit[2]) + @MDAY
    If $alterintagen >= $days Then
    return 1
    Else
    Return 0
    EndIf
    ElseIf ((@MON - $zeit[1]) > 1) Then
    ;Datei ist älter als ein Monat, also Löschen
    Return 1
    EndIf
    EndIf
    ElseIf $zeit[0] < @YEAR Then
    If ((@YEAR - $zeit[0]) = 1) Then
    If @MON Then
    If ($zeit[1] = 12) Then
    $alterintagen = (31 - $zeit[2]) + @MDAY
    If $alterintagen >= $days Then
    return 1
    Else
    Return 0
    EndIf
    EndIf
    EndIf

    ElseIf ((@YEAR - $zeit[0]) > 1) Then
    ;Datei ist älter als ein Jahr
    EndIf
    Return 1
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Return 0

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    #cs
    Func deleteemtpydirectories ($pfad)

    $search = FileFindFirstFile($pfad & "\*")

    [/autoit] [autoit][/autoit] [autoit]

    ; Prüfen, ob die Suche erfolgreich war
    If $search = -1 Then
    ;MsgBox(0, "Fehler", "Es wurden keine Dateien/Verzeichnisse gefunden, die zu dem Suchmuster passen")
    Exit
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $file = FileFindNextFile($search)
    If @error Then
    ExitLoop
    Else
    If @extended Then
    ;Wenn @extended gleich 1 ist, ist die "datei" ein Ordner, also ruft die Funktion sich selbst mit dem Ordner Pfad auf.
    deleteloop ($pfad & "\" & $file)
    Else
    ;@extended gleich 0, also Alter Prüfen
    If (deleteold($pfad & "\" & $file, 7)) = 1 Then
    ;MsgBox ( 0 , "" , "datei '" & $file & "' wird gelöscht" , "" , "")
    FileDelete($pfad & "\" & $file)
    Else
    ;MsgBox ( 0 , "" , "datei '" & $file &"' wird nicht gelöscht" , "" , "")
    EndIf
    EndIf
    EndIf
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    ; Handle für Suche schliessen
    FileClose($search)

    EndFunc
    #ce

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func deleteloop ($pfad)

    $search = FileFindFirstFile($pfad & "\*")

    [/autoit] [autoit][/autoit] [autoit]

    ; Prüfen, ob die Suche erfolgreich war
    If $search = -1 Then
    MsgBox(0, "Fehler", "Es wurden keine Dateien/Verzeichnisse gefunden, die zu dem Suchmuster passen")
    ;Hier bricht das ganze Script ab.
    Exit
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $file = FileFindNextFile($search)
    If @error Then
    ExitLoop
    Else
    If @extended Then
    ;Wenn @extended gleich 1 ist, ist die "datei" ein Ordner, also ruft die Funktion sich selbst mit dem Ordner Pfad auf.
    deleteloop ($pfad & "\" & $file)
    Else
    ;@extended gleich 0, also Alter Prüfen
    If (deleteold($pfad & "\" & $file, 7)) = 1 Then
    ;MsgBox ( 0 , "" , "datei '" & $file & "' wird gelöscht" , "" , "")
    FileDelete($pfad & "\" & $file)
    Else
    ;MsgBox ( 0 , "" , "datei '" & $file &"' wird nicht gelöscht" , "" , "")
    EndIf
    EndIf
    EndIf
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    ; Handle für Suche schliessen
    FileClose($search)

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    deleteloop ("D:\testordner")

    [/autoit]

    Ich habe übrigens ziemlich viel aus der AutoIT Dokumentation geklaut, die ist echt gut.

    Einmal editiert, zuletzt von thedoginthewok (22. August 2012 um 15:13) aus folgendem Grund: Gelöst

    • Offizieller Beitrag

    Du muß zusätzlich abfragen ob die Datei ein Verzeichnis ist mit FileGetAttrib.
    Wenn es ein Verzeichnis ist, nützt dir FileDelete herzlich wenig. Verzeichnise löscht man mit DirRemove.

  • Warum machst du es denn nicht einfach so: ?(

    Spoiler anzeigen
    [autoit]

    #include <Date.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Func _DeleteOldFiles($Path, $Time)
    If StringRight($Path, 1) <> '\' Then $Path &= '\'
    $Search = FileFindFirstFile($Path)
    While 1
    $File = FileFindNextFile($Search)
    If @error Then
    ExitLoop
    ElseIf @extended Then
    _DeleteOldFiles($Path & $File & '\', $Time)
    Else
    $FileTime = FileGetTime($Path & $File, Default, 0)
    If IsArray($FileTime) Then Dim $StartTime = $FileTime[0] & '/' & $FileTime[1] & '/' & $FileTime[2] & ' ' & $FileTime[3] & ':' & $FileTime[4] & ':' & $FileTime[5]
    If _DateDiff('D', $StartTime, @YEAR & '/' & @MON & '/' & @MDAY & ' ' & @HOUR & ':' & @MIN & ':' & @SEC) > $Time Then FileDelete($Path & $File)
    EndIf
    WEnd
    EndFunc ;==>_DeleteOldFiles

    [/autoit]

    Achtung: Ungetestet!

    LG
    Christoph :)

  • Spoiler anzeigen

    Du muß zusätzlich abfragen ob die Datei ein Verzeichnis ist mit FileGetAttrib.
    Wenn es ein Verzeichnis ist, nützt dir FileDelete herzlich wenig. Verzeichnise löscht man mit DirRemove.


    Dann ist der Befehl aber in der Hilfe falsch beschrieben.

    Spoiler anzeigen
    [autoit]

    FileDelete ( "path" )

    [/autoit]

    Note: If the "path" passed to FileDelete is a folder, the files therein will be deleted just as if you had used the *.* mask.
    See FileFindFirstFile for a discussion of wildcards.

    Edit: Hoppla...da hab ich doch schon wieder was falsch gelesen :D
    Toll diese Lösung hätte ich schon vor 3 Stunden gewusst :rofl:

    Bild1: Ich beim debuggen

  • Raupi

    Ob die Datei ein Verzeichnis ist, sehe ich ja an dem @extended macro.

    BinDannMalWeg

    Ich kannte das Datei Include nicht, aber der Teil funktioniert ja schon. Deine Lösung ist zwar sehr schön und kurz, aber da werden doch Ordner genauso behandelt, wie bei meinem Script. Oder hab ich was übersehen ?

    Vielen Dank, das ihr euch das anguckt.

    • Offizieller Beitrag
    Zitat von thedoginthewok

    Raupi

    Ob die Datei ein Verzeichnis ist, sehe ich ja an dem @extended macro.

    Das beiFileFindNextFile @extended auf 1 bei einem Verzeichnis gesetzt wird, wußte ich nicht.
    Hab den Befehl auch noch nie benutzt. ;) Deshalb hab ich auch die Hilfe dazu nicht gelesen :D
    Was hindert dich aber jetzt daran, bei @extended = 1 DirRemove anstatt FileDelete zu verwenden?

    Versuch es doch einfach einzubauen oder willst du ein fertiges Script?


    Zitat von General Kaboom

    Edit: Hoppla...da hab ich doch schon wieder was falsch gelesen :D
    Toll diese Lösung hätte ich schon vor 3 Stunden gewusst :rofl:

    Englisch ist schwer.
    Und was hättest du jetzt gewußt ?

  • Raupi : Das man mit FileDelete keine Ordner löschen kann...ich war bereits am schreiben doch dann hab ich die Hilfe gelesen und dort anscheinend was falsch verstanden, weshalb ich dann doch nichts geschrieben habe (bin ETWAS zerschtreut atm.)

    Bild1: Ich beim debuggen

    • Offizieller Beitrag

    Dafür, das du nichts geschrieben hast, ist aber eine Menge draus geworden. :rofl:

  • Wenn ich an der Stelle einfach DirRemove mache, dann versuche ich ja immer zu löschen, egal ob der Ordner leer ist oder nicht. Ich will aber das es erst alle Dateien und Unterordner auf Alter überprüft und dann löscht. (Und mit Dateien funktioniert das auch gut.)

    • Offizieller Beitrag

    Dann überprüf halt das Verzeichnis mit DirGetSize. Im Rückgabearray stehen die Dateien und Unterverzeichnisse.

    Zitat von Hilfe

    flag [optional] Dieses Flag bestimmt das Verhalten und Ergebnis der Funktion und kann eine Kombination der folgenden Werte sein:
    0 = (Standard)
    1 = aktiviert den erweiterten Modus ("Extended mode") -> Es wird ein Array zurückgegeben, das weitere Informationen enthält (siehe Bemerkungen).
    2 = beziehe Dateien in Unterverzeichnissen nicht mit ein (der Rekursivmodus ist aus).


    Also Flag 1 benutzen ;)

  • So vielen dank an euch alle. Das Skript funktioniert so weit.

    Spoiler anzeigen
    [autoit]

    #include <Date.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Func _DeleteOldFiles($Path, $Time)
    If StringRight($Path, 1) <> '\' Then $Path &= '\'
    $Search = FileFindFirstFile($Path & '*')
    While 1
    $File = FileFindNextFile($Search)
    If @error Then
    ExitLoop
    ElseIf @extended Then
    DirRemove ($Path & $File & '\')
    _DeleteOldFiles($Path & $File & '\', $Time)
    Else
    $FileTime = FileGetTime($Path & $File, Default, 0)
    If IsArray($FileTime) Then Dim $StartTime = $FileTime[0] & '/' & $FileTime[1] & '/' & $FileTime[2] & ' ' & $FileTime[3] & ':' & $FileTime[4] & ':' & $FileTime[5]
    If _DateDiff('D', $StartTime, @YEAR & '/' & @MON & '/' & @MDAY & ' ' & @HOUR & ':' & @MIN & ':' & @SEC) > $Time Then FileDelete($Path & $File)
    EndIf
    WEnd
    EndFunc ;==>_DeleteOldFiles

    [/autoit] [autoit][/autoit] [autoit]

    _DeleteOldFiles ("D:\testordner", 7)

    [/autoit]

    Ich habe einfach vor dem rekursiven Aufruf der Funktion ein dirremove eingefügt, das löscht ordner standardmäßig nur dann wenn sie leer sind. Bei meinen Tests hat alles so funktioniert wie es soll, viele Dank nochmals.