Ältere Dateien Löschen

  • Hallo allerseits,

    anscheinend bin ich zu blöd oder gehe von falschen Voraussetzungen aus :(

    Ich verwende die UDF von Oscar und Micha_he namens _FileDeleteAfterXDays. Diese löscht mir tadellos alle Dateien und ev. auch Ordner, die ein gewisses Alter haben. Soweit so gut. Ich will jedoch nicht alle Dateien in einer unbestimmten Anzahl von Ordnern, sondern nur jene, mit einer bestimmten Endung (z.B. *.pdf). Habe nun schon einiges versucht bin aber immer klaglos gescheitert. Ist eine Datei mit der Endung (z.B. *.pdf) im Rootverzeichnis vorhanden, wird sie gelöscht. Alle anderen Dateien in den weiteren Unterverzeichnissen bleiben aber stehen.

    Die ursprüngliche Funktion:

    Spoiler anzeigen
    [autoit]

    #include <Date.au3>
    #include <File.au3>
    #include <Array.au3>
    $Server=("C:\Temp")
    $Tage=1
    $Filter=("*.pdf")
    _FileDeleteAfterXDays($Server,$Tage,True,True,True,True)
    ;===============================================================================
    ; Function Name: _FileDeleteAfterXDays($sPath, $iDays[, $bForceDel][, $bRek][, $bDirDel][, $bLog])
    ; Description:: löscht Dateien in einem ausgewähltem Verzeichnis (rekursiv)
    ; nach einer angegebenen Anzahl von Tagen
    ; Parameter(s): $sPath = Verzeichnis, aus dem die Dateien gelöscht werden sollen.
    ; $iDays = Dateien, die älter als $iDays (in Tagen) sind, löschen.
    ; $bForceDel = wenn "True" werden auch Dateien/Verzeichnisse gelöscht,
    ; die gegen löschen geschützt sind ("R"-Attribut)
    ; $bRek = wenn "True" wird das Verzeichnis rekursiv (inkl. Unter-
    ; verzeichnisse) durchsucht.
    ; $bDirDel = wenn "True" wird das Unterverzeichnis gelöscht, wenn
    ; es (aufgrund der Löschaktion) leer ist.
    ; $bLog = wenn "True" wird das Ergebnis der Löschaktion in die
    ; Console geschrieben.
    ; Requirement(s): AutoIt-Version min. v3.3.2.0
    ; #include <Date.au3>
    ; Return Value(s): bei Erfolg Rückgabe = 1
    ; bei Fehler Rückgabe = 0
    ; und @error:
    ; 1 = $iDays ist keine oder eine negative Zahl
    ; 2 = Das übergebene Verzeichnis existiert nicht oder ist leer.
    ; Author(s): Oscar (http://www.autoit.de)
    ; Micha_he (http://www.autoit.de)
    ;
    ;===============================================================================
    Func _FileDeleteAfterXDays($sPath, $iDays, $bForceDel = False, $bRek = True, $bDirDel = True, $bLog = True)
    Local $hSearchm, $hEmpty, $sFile, $sDate, $iRet
    If (Not IsNumber($iDays)) Or ($iDays < 0) Then Return SetError(1, 0, 0)
    If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
    $hSearch = FileFindFirstFile($sPath & '*.*')
    If @error Then Return SetError(2, 0, 0)
    While 1
    $sFile = FileFindNextFile($hSearch)
    If @error Then ExitLoop
    If @extended Then
    If $bRek Then
    _FileDeleteAfterXDays($sPath & $sFile, $iDays, $bForceDel, $bRek, $bDirDel, $bLog)
    If $bDirDel Then
    $hEmpty = FileFindFirstFile($sPath & $sFile & '\*.*')
    If @error Then
    If $bForceDel Then FileSetAttrib($sPath & $sFile, '-R')
    $iRet = DirRemove($sPath & $sFile)
    If $bLog Then ConsoleWrite('Delete Folder "' & $sPath & $sFile & '" = ' & StringMid('No Yes', $iRet * 3 + 1, 3) & @CR)
    EndIf
    FileClose($hEmpty)
    EndIf
    EndIf
    Else
    $sDate = StringRegExpReplace(FileGetTime($sPath & $sFile, 0, 1), '(\d{4})(\d{2})(\d{2})(.*)', '$1/$2/$3')
    If _DateDiff('D', $sDate, _NowCalc()) > $iDays Then
    If $bForceDel Then FileSetAttrib($sPath & $sFile, '-R')
    $iRet = FileDelete($sPath & $sFile)
    If $bLog Then ConsoleWrite('Delete File "' & $sPath & $sFile & '" = ' & StringMid('No Yes', $iRet * 3 + 1, 3) & @CR)
    EndIf
    EndIf
    WEnd
    FileClose($hSearch)
    Return 1
    EndFunc

    [/autoit]


    Wäre absolut toll, wenn mir jemand helfen könnte.

    lg

    Merlin

    Einmal editiert, zuletzt von mr_merlin (2. November 2012 um 09:36) aus folgendem Grund: Dank aller hat alles gut funktioniert. Deshalb habe ich den Status auf gelöst gestellt.

  • versuch mal hier mit:

    [autoit]


    #include <Date.au3>
    #include <File.au3>
    #include <Array.au3>
    $Server=("C:\Temp")
    $Tage=1
    $Filter="*.pdf"
    _FileDeleteAfterXDays($Server,$Tage,True,True,True,True)
    ;===============================================================================
    ; Function Name: _FileDeleteAfterXDays($sPath, $iDays[, $bForceDel][, $bRek][, $bDirDel][, $bLog])
    ; Description:: löscht Dateien in einem ausgewähltem Verzeichnis (rekursiv)
    ; nach einer angegebenen Anzahl von Tagen
    ; Parameter(s): $sPath = Verzeichnis, aus dem die Dateien gelöscht werden sollen.
    ; $iDays = Dateien, die älter als $iDays (in Tagen) sind, löschen.
    ; $bForceDel = wenn "True" werden auch Dateien/Verzeichnisse gelöscht,
    ; die gegen löschen geschützt sind ("R"-Attribut)
    ; $bRek = wenn "True" wird das Verzeichnis rekursiv (inkl. Unter-
    ; verzeichnisse) durchsucht.
    ; $bDirDel = wenn "True" wird das Unterverzeichnis gelöscht, wenn
    ; es (aufgrund der Löschaktion) leer ist.
    ; $bLog = wenn "True" wird das Ergebnis der Löschaktion in die
    ; Console geschrieben.
    ; Requirement(s): AutoIt-Version min. v3.3.2.0
    ; #include <Date.au3>
    ; Return Value(s): bei Erfolg Rückgabe = 1
    ; bei Fehler Rückgabe = 0
    ; und @error:
    ; 1 = $iDays ist keine oder eine negative Zahl
    ; 2 = Das übergebene Verzeichnis existiert nicht oder ist leer.
    ; Author(s): Oscar (http://www.autoit.de)
    ; Micha_he (http://www.autoit.de)
    ;
    ;===============================================================================
    Func _FileDeleteAfterXDays($sPath, $iDays, $bForceDel = False, $bRek = True, $bDirDel = True, $bLog = True)
    Local $hSearchm, $hEmpty, $sFile, $sDate, $iRet
    If (Not IsNumber($iDays)) Or ($iDays < 0) Then Return SetError(1, 0, 0)
    If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
    $hSearch = FileFindFirstFile($sPath & $Filter)
    If @error Then Return SetError(2, 0, 0)
    While 1
    $sFile = FileFindNextFile($hSearch)
    If @error Then ExitLoop
    If @extended Then
    If $bRek Then
    _FileDeleteAfterXDays($sPath & $sFile, $iDays, $bForceDel, $bRek, $bDirDel, $bLog)
    If $bDirDel Then
    $hEmpty = FileFindFirstFile($sPath & $sFile & "\" &$Filter)
    If @error Then
    If $bForceDel Then FileSetAttrib($sPath & $sFile, '-R')
    $iRet = DirRemove($sPath & $sFile)
    If $bLog Then ConsoleWrite('Delete Folder "' & $sPath & $sFile & '" = ' & StringMid('No Yes', $iRet * 3 + 1, 3) & @CR)
    EndIf
    FileClose($hEmpty)
    EndIf
    EndIf
    Else
    $sDate = StringRegExpReplace(FileGetTime($sPath & $sFile, 0, 1), '(\d{4})(\d{2})(\d{2})(.*)', '$1/$2/$3')
    If _DateDiff('D', $sDate, _NowCalc()) > $iDays Then
    If $bForceDel Then FileSetAttrib($sPath & $sFile, '-R')
    $iRet = FileDelete($sPath & $sFile)
    If $bLog Then ConsoleWrite('Delete File "' & $sPath & $sFile & '" = ' & StringMid('No Yes', $iRet * 3 + 1, 3) & @CR)
    EndIf
    EndIf
    WEnd
    FileClose($hSearch)
    Return 1
    EndFunc

    [/autoit]

    :thumbup:

    Einmal editiert, zuletzt von bobekos (30. Oktober 2012 um 16:18)

  • Vorerst danke für die rasche Antwort.

    Es löscht zwar wunderbar das *.pdf-File aus dem Root-Verzeichnis. Das war es aber schon. Alle rekursiv aufgerufenen Unterverzeichnisse bleiben aber leider unberührt.

  • Hier eine etwas andere Version mit der Rekursiven Filesuche von BugFix, sollte so funktionieren ;)

    Spoiler anzeigen
    [autoit]

    #include <Date.au3>
    #include <File.au3>
    #include <Array.au3>
    $Server = "C:\xampp\tomcat" ;Verzeichnis
    $Tage = 1 ;alter der Tage
    $Filter = ".pdf" ;Nur pdf´s
    $bForceDel = False ; Löschen erzwingen
    $bLog = True ; Logging aktivieren
    $Array = _GetFilesFolder_Rekursiv($Server, $Filter, 0)
    _arraydisplay($Array)
    For $i = 1 To UBound($Array) - 1
    $sDate = StringRegExpReplace(FileGetTime($Array[$i], 0, 1), '(\d{4})(\d{2})(\d{2})(.*)', '$1/$2/$3')
    If _DateDiff('D', $sDate, _NowCalc()) > $Tage Then
    If $bForceDel Then FileSetAttrib($Array[$i], '-R')
    $iRet = FileDelete($Array[$i])
    If $bLog Then ConsoleWrite('Delete File "' & $Array[$i] & '" = ' & StringMid('No Yes', $iRet * 3 + 1, 3) & @CRLF)
    EndIf
    Next
    ; #FUNCTION#
    ;==================================================================================================
    ; Function Name: _GetFilesFolder_Rekursiv($sPath [, $sExt='*' [, $iDir=-1 [, $iRetType=0 ,[$sDelim='0']]]])
    ; Description: Rekursive Auflistung von Dateien und/oder Ordnern
    ; Parameter(s): $sPath der Basispfad für die Auflistung ('.' -aktueller Pfad, '..' -Parentpfad)
    ; $sExt Erweiterung für Dateiauswahl '*' oder -1 für alle (Standard)
    ; $iDir -1 Dateien+Ordner(Standard), 0 nur Dateien, 1 nur Ordner
    ; optional: $iRetType 0 gibt Array, 1 gibt String zurück
    ; optional: $sDelim legt Trennzeichen für Stringrückgabe fest
    ; 0 -@CRLF (Standard) 1 -@CR 2 -@LF 3 -';' 4 -'|'
    ; Return Value(s): Array (Standard) od. String mit den gefundenen Pfaden der Dateien und/oder Ordner
    ; Array[0] enthält die Anzahl der gefundenen Dateien/Ordner
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;==================================================================================================
    Func _GetFilesFolder_Rekursiv($sPath, $sExt = '*', $iDir = -1, $iRetType = 0, $sDelim = '0', $bProcess = False)
    Global $oFSO = ObjCreate('Scripting.FileSystemObject')
    Global $strFiles = ''
    Switch $sDelim
    Case '1'
    $sDelim = @CR
    Case '2'
    $sDelim = @LF
    Case '3'
    $sDelim = ';'
    Case '4'
    $sDelim = '|'
    Case Else
    $sDelim = @CRLF
    EndSwitch
    If ($iRetType < 0) Or ($iRetType > 1) Then $iRetType = 0
    If $sExt = -1 Then $sExt = '*'
    If ($iDir < -1) Or ($iDir > 1) Then $iDir = -1
    _ShowSubFolders($oFSO.GetFolder($sPath), $sExt, $iDir, $sDelim, $bProcess)
    If $iRetType = 0 Then
    Local $aOut
    $aOut = StringSplit(StringTrimRight($strFiles, StringLen($sDelim)), $sDelim, 1)
    If $aOut[1] = '' Then
    ReDim $aOut[1]
    $aOut[0] = 0
    EndIf
    Return $aOut
    Else
    Return StringTrimRight($strFiles, StringLen($sDelim))
    EndIf
    EndFunc ;==>_GetFilesFolder_Rekursiv
    Func _ShowSubFolders($Folder, $Ext = '*', $Dir = -1, $Delim = @CRLF, $bProcess = False)
    If Not IsDeclared("strFiles") Then Global $strFiles = ''
    If ($Dir = -1) Or ($Dir = 0) Then
    For $file In $Folder.Files
    If $Ext <> '*' Then
    If StringRight($file.Name, StringLen($Ext)) = $Ext Then _
    $strFiles &= $file.Path & $Delim
    Else
    $strFiles &= $file.Path & $Delim
    EndIf
    Next
    EndIf
    For $Subfolder In $Folder.SubFolders
    If ($Dir = -1) Or ($Dir = 1) Then $strFiles &= $Subfolder.Path & '\' & $Delim
    _ShowSubFolders($Subfolder, $Ext, $Dir, $Delim)
    Next
    EndFunc ;==>_ShowSubFolders

    [/autoit]
  • Ich habe vor längerer Zeit Oscars Funktion erweitert damit man mehrere Dteitypen auf eimal löschen kann. Bei mir hat die Funktion zur Zufriedenheit gearbeitet.

    'FilesDeleteAfter.au3&quot;
    [autoit]

    #include-once
    #include <Date.au3>
    #include <Array.au3>

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

    ;===============================================================================
    ; Function Name: _FileDeleteAfterXDays($sPath, $iDays[, $bForceDel][, $bRek][, $bDirDel][, $bLog], [$sFilter])
    ; Description:: löscht Dateien in einem ausgewähltem Verzeichnis (rekursiv)
    ; nach einer angegebenen Anzahl von Tagen
    ; Parameter(s): $sPath = Verzeichnis, aus dem die Dateien gelöscht werden sollen.
    ; $iDays = Dateien, die älter als $iDays (in Tagen) sind, löschen.
    ; $bForceDel = wenn "True" werden auch Dateien/Verzeichnisse gelöscht,
    ; die gegen löschen geschützt sind ("R"-Attribut)
    ; $bRek = wenn "True" wird das Verzeichnis rekursiv (inkl. Unter-
    ; verzeichnisse) durchsucht.
    ; $bDirDel = wenn "True" wird das Unterverzeichnis gelöscht, wenn
    ; es (aufgrund der Löschaktion) leer ist.
    ; $bLog = wenn "True" wird das Ergebnis der Löschaktion in die
    ; Console geschrieben.
    ; $sFilter hier können Dateierweiterungen (mit | getrennt) gegeben werden für welche die Löschaktion gilt *=alle
    ; Requirement(s): AutoIt-Version min. v3.3.2.0
    ; #include <Date.au3>
    ; Return Value(s): bei Erfolg Rückgabe = 1
    ; bei Fehler Rückgabe = 0
    ; und @error:
    ; 1 = $iDays ist keine oder eine negative Zahl
    ; 2 = Das übergebene Verzeichnis existiert nicht oder ist leer.
    ; Author(s): Oscar (http://www.autoit.de)
    ; Micha_he (http://www.autoit.de)
    ; modified: autoBert 18.05.12 um $sFilter erweitert
    ; Example: _FileDeleteAfterXDays('c:\', 10, True, True, True, True, "bak|tmp|tst")
    ;===============================================================================
    Func _FileDeleteAfterXDays($sPath, $iDays, $bForceDel = False, $bRek = True, $bDirDel = True, $bLog = True, $sFilter = "*")
    Local $hSearchm, $hEmpty, $sFile, $sDate, $iRet
    ;ConsoleWrite($sFilter & @CRLF)
    Local $aFilter = StringSplit($sFilter, "|")
    If @error Then
    $aFilter[0] = $sFilter
    _ArrayDelete($aFilter, 1)
    Else
    _ArrayDelete($aFilter, 0)
    EndIf
    If (Not IsNumber($iDays)) Or ($iDays < 0) Then Return SetError(1, 0, 0)
    If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
    $hSearch = FileFindFirstFile($sPath & '*.*')
    If @error Then Return SetError(2, 0, 0)
    While 1
    $sFile = FileFindNextFile($hSearch)
    If @error Then ExitLoop
    If @extended Then
    If $bRek Then
    _FileDeleteAfterXDays($sPath & $sFile, $iDays, $bForceDel, $bRek, $bDirDel, $bLog, $sFilter)
    If $bDirDel Then
    $hEmpty = FileFindFirstFile($sPath & $sFile & '\*.*')
    If @error Then
    If $bForceDel Then FileSetAttrib($sPath & $sFile, '-R')
    $iRet = DirRemove($sPath & $sFile)
    If $bLog Then ConsoleWrite('Delete Folder "' & $sPath & $sFile & '" = ' & StringMid('No Yes', $iRet * 3 + 1, 3) & @CR)
    EndIf
    FileClose($hEmpty)
    EndIf
    EndIf
    Else
    $sDate = StringRegExpReplace(FileGetTime($sPath & $sFile, 0, 1), '(\d{4})(\d{2})(\d{2})(.*)', '$1/$2/$3')
    If _DateDiff('D', $sDate, _NowCalc()) > $iDays Then
    $aExt = StringSplit($sPath & $sFile, ".")
    If $aFilter[0] = "*" Then
    $bDel = True
    Else
    $bDel = False
    For $i = 0 To UBound($aFilter) - 1
    If $aExt[$aExt[0]] = $aFilter[$i] Then
    $bDel = True
    ExitLoop
    EndIf
    Next
    EndIf
    If $bDel Then
    If $bForceDel Then FileSetAttrib($sPath & $sFile, '-R')
    $iRet = FileDelete($sPath & $sFile)
    If $bLog Then ConsoleWrite('Delete File "' & $sPath & $sFile & '" = ' & StringMid('No Yes', $iRet * 3 + 1, 3) & @CR)
    EndIf
    EndIf
    EndIf
    WEnd
    FileClose($hSearch)
    Return 1
    EndFunc ;==>_FileDeleteAfterXDays

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

    ;#cs
    #include <FilesDeleteAfter.au3>

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

    _FileDeleteAfterXDays('C:\Temp', 10)
    #ce

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

    Aufruf:

    [autoit]

    #include <FilesDeleteAfter.au3>

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

    _FileDeleteAfterXDays('c:\', 10, True, True, True, True, "pdf|bak|tst" ;löscht alle .pdf und alle *.bak und alle .tst auf Laufwerk c: die älter ls10 Tage sind
    _FileDeleteAfterXDays('c:\Temp', 10" ;löscht alle Dteien in c:\Temp die älter als 10 Tage sind mit usnhme der versteckten

    [/autoit]

    mfg autoBert

    Einmal editiert, zuletzt von autoBert (31. Oktober 2012 um 14:18)

  • Hallo autoBert,

    genau das, woran ich gescheitert bin, hast du geschafft - funktioniert tadellos - RESPEKT und DANKE !!!!!!!

    Das einzige was noch nicht funktioniert ist, das alle (*.* - in deinem Skript nur *) Dateien in den rekursiven Ordner löschen. Macht aber ürberhaupt nichts. Diesen Umstand werde ich auch allene lösen können.

    lg

    Merlin

    Einmal editiert, zuletzt von mr_merlin (31. Oktober 2012 um 13:15) aus folgendem Grund: Ergänzung

  • Es gibt nur ein ReDim kurz vor dem Return des Arrays,
    Ich lasse mal einen Vergleich laufen und poste die Geschwindigkeitsergebnisse

  • Das einzige was noch nicht funktioniert ist, das alle (*.* - in deinem Skript nur *) Dateien in den rekursiven Ordner löschen.


    Da ich damals nur die Anforderung hatte mehrere Dateitypen in einem Rutsch zu löschen habe ich anscheinend auch nur dieses getestet. Habe den Fehler behoben (und das Skript im vorhergehenden Beitrag ausgetauscht).

    TheLuBu: ich vermute dass deine Lösung schneller ist, da bei mir ja jedesmal geprüft wird ob der Dateityp im Filter vorkommt, dafür ist meine Lösung dann auf jeden Fall schneller sobald mehrere Dateitypen so gelöscht werden sollen.

    mfg autoBert

  • autoBert

    Dieses Script hat nun wirklich alles, was man benötigt. Die Geschwindigkeit ist absolut gut. Die rekursiven Aufrufe der Unterverzeichnisse sind absolut zuverlässig und schnell. Danke nochmals für deine Hilfe!!!!!!!

    Vielen Dank auch für die anderen Lösungsmöglichkeit, die ebenfalls super funktionieren und für die Mühe eurer Posts.


    lg

    mr_merlin