Rekursives Löschen von Verzeichnissen wenn Dateien bestimmtes Alter erreicht haben
Hallo zusammen,
nun möchte ich doch die Gemeinde mal befragen. Nach dem x-ten Versuch habe ich immer noch keine brauchbare Lösung für dieses Problem. Wie so oft geht es um das Löschen von Daten in einem temporären Bereich nach einer bestimmen Zeit.
Aber.
Das Kriterium ist nicht das Datum einer Datei oder eines Verzeichnisses, sondern ergibt sich aus den jüngsten Dateien innerhalb einer Struktur. Ausgehend von einem Startverzeichnis (z.B. c:\temp) sollen alle Verzeichnisse gelöscht werden, in denen es seit n Tagen keine Änderung gab. Jetzt kann es aber beliebig viele Unterverzeichnisse geben, mit wieder beliebig vielen Unterverzeichnissen,...
Eine Datei oder ein Verzeichnis in irgend einem der Unterverzeichnisse mit einem kleineren n muss das Löschen des ganzen Zweiges (nach oben hin gesehen) verhindern.
Also anders formuliert, ein Script (oder der Ansatz zu einem) wird gesucht, das ein Verzeichnis nur löscht (rekursiv), wenn es in ihm keine Dateien oder Verzeichnisse gibt, die jünger sind als ein Anzahl von Tagen n.
Hoffentlich kann meiner Beschreibung jemand folgen...
Ultrasparc
nun möchte ich doch die Gemeinde mal befragen. Nach dem x-ten Versuch habe ich immer noch keine brauchbare Lösung für dieses Problem. Wie so oft geht es um das Löschen von Daten in einem temporären Bereich nach einer bestimmen Zeit.
Aber.
Das Kriterium ist nicht das Datum einer Datei oder eines Verzeichnisses, sondern ergibt sich aus den jüngsten Dateien innerhalb einer Struktur. Ausgehend von einem Startverzeichnis (z.B. c:\temp) sollen alle Verzeichnisse gelöscht werden, in denen es seit n Tagen keine Änderung gab. Jetzt kann es aber beliebig viele Unterverzeichnisse geben, mit wieder beliebig vielen Unterverzeichnissen,...
Eine Datei oder ein Verzeichnis in irgend einem der Unterverzeichnisse mit einem kleineren n muss das Löschen des ganzen Zweiges (nach oben hin gesehen) verhindern.
Also anders formuliert, ein Script (oder der Ansatz zu einem) wird gesucht, das ein Verzeichnis nur löscht (rekursiv), wenn es in ihm keine Dateien oder Verzeichnisse gibt, die jünger sind als ein Anzahl von Tagen n.
Hoffentlich kann meiner Beschreibung jemand folgen...
Ultrasparc
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 94397
Url: https://administrator.de/contentid/94397
Ausgedruckt am: 22.11.2024 um 04:11 Uhr
16 Kommentare
Neuester Kommentar
Hallo Ultrasparc und willkommen im Forum!
Etwas zum Testen:
Dieses VBScript erwartet die Übergabe eines Startverzeichnisses (zB per Drag & Drop) bzw verwendet alternativ das Default-Verzeichnis lt Zeile 3. (Derzeit wird noch nicht überprüft, ob das Startverzeichnis existiert.)
Wird die Logdatei im Startverzeichnis erstellt, bleibt dieses auf jeden Fall erhalten; falls dies nicht gewünscht ist, kann die Zeile 4 durch die Zeile 5 (ohne das Apostroph am Anfang) mit der Angabe eines anderen Pfades ersetzt werden.
Um gefahrlos testen zu können, kannst Du die Zeile 37
durch ein vorangestelltes Apostroph "entschärfen" - allerdings werden dann in der Struktur höher liegende Verzeichnisse natürlich immer als "nicht zu löschend" angegeben, da ja die Unterverzeichnisse auf jeden Fall erhalten bleiben (was bei aktiver Löschfunktion nur der Fall wäre, wenn diese tatsächlich jüngere Dateien enthielten).
Leere Verzeichnisse werden (im Ernstfall) immer gelöscht, da sich darin ja keine "erhaltenswerte" Datei befindet.
Grüße
bastla
Etwas zum Testen:
'DOF.vbs
Alter = 10 'Anzahl der Tage
StartOrdner = "C:\Temp"
If WScript.Arguments.Count > 0 Then StartOrdner = WScript.Arguments(0)
LogDatei = StartOrdner & "\Log.txt" 'verhindert Löschen des Startordners
'LogDatei = "D:\Log.txt"
Set fso = CreateObject("Scripting.FileSystemObject")
Set L = fso.CreateTextFile(LogDatei, True)
Heute = Date()
L.WriteLine "Löschen mit Alter von mehr als " & Alter & " Tagen (= jüngstem Änderungsdatum vor " & Heute - Alter & ")"
L.WriteLine
DeleteInFolder fso.GetFolder(StartOrdner)
L.Close
WScript.Echo "Fertig."
Sub DeleteInFolder(Ordner)
For Each Unter In Ordner.SubFolders
DeleteInFolder(Unter)
Next
WegDamit = True
If Ordner.SubFolders.Count > 0 Then
WegDamit=False
L.WriteLine "## """ & Ordner.Path & """ enthält Unterordner. ##"
Else
For Each Datei In Ordner.Files
L.WriteLine Heute - Int(Datei.DateLastModified) & vbTab & Datei.DateLastModified & " """ & Datei.Path & """"
If Datei.DateLastModified > (Heute - Alter) Then
WegDamit = False
Exit For
End If
Next
End If
If WegDamit Then
L.WriteLine "--- """ & Ordner.Path & """ wird gelöscht. ---"
Ordner.Delete(True)
Else
L.WriteLine "+++ """ & Ordner.Path & """ wird nicht gelöscht. +++"
End If
End Sub
Wird die Logdatei im Startverzeichnis erstellt, bleibt dieses auf jeden Fall erhalten; falls dies nicht gewünscht ist, kann die Zeile 4 durch die Zeile 5 (ohne das Apostroph am Anfang) mit der Angabe eines anderen Pfades ersetzt werden.
Um gefahrlos testen zu können, kannst Du die Zeile 37
Ordner.Delete(True)
Leere Verzeichnisse werden (im Ernstfall) immer gelöscht, da sich darin ja keine "erhaltenswerte" Datei befindet.
Grüße
bastla
Hallo Ultrasparc!
Entsprechend Deinem Beispiel müsste dann aber bei Ordnern das Erstellungsdatum zum Kriterium gemacht werden - dazu die Zeilen 19-21 durch
ersetzen.
Allerdings stellt sich mir die Frage, was einen neuen Ordner mit alten Daten erhaltenswert macht ...
Grüße
bastla
Entsprechend Deinem Beispiel müsste dann aber bei Ordnern das Erstellungsdatum zum Kriterium gemacht werden - dazu die Zeilen 19-21 durch
For Each Unter In Ordner.SubFolders
L.WriteLine "## " & Heute - Int(Unter.DateCreated) & vbTab & Unter.Created & " """ & Unter.Path & """ ##"
If Unter.DateCreated <= (Heute - Alter) Then
DeleteInFolder(Unter)
Else
L.WriteLine "+++ """ & Unter.Path & """ wird nicht gelöscht. +++"
End If
Next
Allerdings stellt sich mir die Frage, was einen neuen Ordner mit alten Daten erhaltenswert macht ...
Grüße
bastla
Hallo Ultrasparc!
Größer ist das Risiko durch Verwendung von "DateCreated" aber eigentlich auch nicht - es wird ja hier nicht gelöscht, wenn das Erstellungsdatum neu genug ist, anderenfalls werden aber ohnehin die Inhalte noch überprüft.
Grüße
bastla
Kann ich das einfach mit 'DateLastModified' ersetzen?
Wenn Du das Risiko eingehen willst, dass ein Ordner nicht gelöscht wird, weil gestern eine Datei darin gelöscht wurde und daher sein Änderungsdatum auf gestern steht ...Größer ist das Risiko durch Verwendung von "DateCreated" aber eigentlich auch nicht - es wird ja hier nicht gelöscht, wenn das Erstellungsdatum neu genug ist, anderenfalls werden aber ohnehin die Inhalte noch überprüft.
Grüße
bastla
Hallo Ultrasparc!
Mit der folgenden Alternative könntest Du übrigens beide Daten ausgeben und auch für die Entscheidung, ob ein Unterverzeichnis überhaupt näher untersucht werden muss, berücksichtigen:
Grüße
bastla
Keine der WriteLine Zeilen stehen im Logfile.
Es müsste in Deiner der Zeile 3 "Unter.DateCreated" heißen, und eigentlich solltest Du eine Fehlermeldung erhalten haben ...Mit der folgenden Alternative könntest Du übrigens beide Daten ausgeben und auch für die Entscheidung, ob ein Unterverzeichnis überhaupt näher untersucht werden muss, berücksichtigen:
L.WriteLine "#### " & Heute - Int(Unter.DateLastModified) & vbTab & Unter.DateLastModified & " **" & Heute - Int(Unter.DateCreated) & "_" & Unter.DateCreated & "** """ & Unter.Path & """ ####"
If Unter.DateCreated <= (Heute - Alter) And Unter.DateLastModified <= (Heute - Alter) Then
Grüße
bastla
Hallo Ultrasparc!
Da Du Dich als Batchfan deklariert hast, eine andere Version (mit gaaaanz wenig VBS ):
Lt Erfahrungswerten (und http://support.microsoft.com/kb/299648/de ) müsste es eigentlich genügen, das Erstellungsdatum nur dann zu überprüfen, wenn es in dem Ordner keine Dateien gibt/gegeben hat (in diesem Fall liefert "%%~tf" auch kein Änderungsdatum).
Grüße
bastla
Da Du Dich als Batchfan deklariert hast, eine andere Version (mit gaaaanz wenig VBS ):
@echo off & setlocal enabledelayedexpansion
set "Startverzeichnis=C:\Temp"
set Alter=10
set S=%temp%\Stichtag.vbs
>%S% echo D=WScript.Arguments(0):N=DateAdd("d",WScript.Arguments(0),Date):WScript.Echo Right(N,4)^&Mid(N,4,2)^&Left(N,2)
for /f %%i in ('cscript //nologo %S% -%Alter%') do set "Stichtag=%%i"
if not defined Stichtag echo Fehler bei Tageberechnung & goto :eof
echo Stichtag: %Stichtag% bei Alter: %Alter%
echo\
for /d %%i in ("%Startverzeichnis%\*.*") do call :Verzeichnis "%%i"
goto :eof
:Verzeichnis
echo ====================================================================
set Behalten=
echo %~t1 %1
for /f "tokens=1-3 delims=. " %%a in ("%~t1") do if %%c%%b%%a geq %Stichtag% set Behalten=True & goto :VerzeichnisFertig
for /f %%f in ('dir /s /b /ad %1') do if not defined Behalten (
if "%%~tf" neq "" (
echo %%~tf "%%f"
for /f "tokens=1-3 delims=. " %%a in ("%%~tf") do if %%c%%b%%a geq %Stichtag% set Behalten=True
) else (
set "Parent=%%~dpf"
for /f "tokens=1-3 delims=. " %%a in ('dir /tc /ad "!Parent!"^|findstr /e c:"%%nxf"') do (
echo %%a.%%b.%%c "%%f"
if %%c%%b%%a geq %Stichtag% set Behalten=True
)
)
)
:VerzeichnisFertig
if not defined Behalten goto :WegDamit
echo --------------------------------------------------------------------
echo ++++ %1 wird nicht entfernt. ++++
echo ====================================================================
echo\
goto :eof
:WegDamit
echo --------------------------------------------------------------------
echo #### %1 wird entfernt. ####
echo ====================================================================
echo\
::rd /s /q %1
goto :eof
Grüße
bastla
Hallo Ultrasparc!
Grüße
bastla
Was mir beim Lesen gleich augefallen ist: kleiner Fehler in Zeile 2 - da ist das Hochkomma verutscht
Freut mich, dass Du so genau liest, allerdings (für alle Mitleser ) ist diese Schreibweise Absicht und erzeugt keinen Fehler, sondern sorgt einerseits dafür, dass der Inhalt der Variablen genau festgelegt wird (und nicht zB Leerzeichen am Ende des Textes mit aufgenommen werden), und dass andererseits die Variable selbst keine Anführungszeichen enthält - letztere kann ich so genau dort, wo ich sie benötige, setzen ...Grüße
bastla