Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit
GELÖST

Rekursives Löschen von Verzeichnissen wenn Dateien bestimmtes Alter erreicht haben

Frage Entwicklung Batch & Shell

Mitglied: Ultrasparc

Ultrasparc (Level 1) - Jetzt verbinden

14.08.2008, aktualisiert 18.08.2008, 7340 Aufrufe, 16 Kommentare

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
Mitglied: bastla
14.08.2008 um 14:04 Uhr
Hallo Ultrasparc und willkommen im Forum!

Etwas zum Testen:
01.
'DOF.vbs 
02.
Alter = 10 'Anzahl der Tage 
03.
StartOrdner = "C:\Temp" 
04.
If WScript.Arguments.Count > 0 Then StartOrdner = WScript.Arguments(0) 
05.
LogDatei = StartOrdner & "\Log.txt" 'verhindert Löschen des Startordners 
06.
'LogDatei = "D:\Log.txt" 
07.
 
08.
Set fso = CreateObject("Scripting.FileSystemObject") 
09.
Set L = fso.CreateTextFile(LogDatei, True) 
10.
 
11.
Heute = Date() 
12.
L.WriteLine "Löschen mit Alter von mehr als " & Alter & " Tagen (= jüngstem Änderungsdatum vor " & Heute - Alter & ")" 
13.
L.WriteLine 
14.
DeleteInFolder fso.GetFolder(StartOrdner) 
15.
L.Close 
16.
WScript.Echo "Fertig." 
17.
 
18.
Sub DeleteInFolder(Ordner) 
19.
For Each Unter In Ordner.SubFolders 
20.
	DeleteInFolder(Unter) 
21.
Next 
22.
WegDamit = True 
23.
If Ordner.SubFolders.Count > 0 Then 
24.
	WegDamit=False 
25.
	L.WriteLine "## """ & Ordner.Path & """ enthält Unterordner. ##" 
26.
Else 
27.
	For Each Datei In Ordner.Files 
28.
		L.WriteLine Heute - Int(Datei.DateLastModified) & vbTab & Datei.DateLastModified & " """ & Datei.Path & """" 
29.
		If Datei.DateLastModified > (Heute - Alter) Then 
30.
			WegDamit = False 
31.
			Exit For 
32.
		End If 
33.
	Next 
34.
End If 
35.
If WegDamit Then 
36.
	L.WriteLine "--- """ & Ordner.Path & """ wird gelöscht. ---" 
37.
	Ordner.Delete(True) 
38.
Else 
39.
	L.WriteLine "+++ """ & Ordner.Path & """ wird nicht gelöscht. +++" 
40.
End If 
41.
End Sub
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
01.
Ordner.Delete(True)
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
Bitte warten ..
Mitglied: Ultrasparc
14.08.2008 um 16:03 Uhr
Vielen Dank erst einmal.

Manche Probleme kann man wohl nicht mit vertretbarem Aufwand in reiner Batch lösen (ich jedenfalls nicht).

Na egal. Ein erster Test in einem neu angelegten Verzeichnis sieht gut aus, im Logfile steht das, was ich erwartet hätte.
Ich werde jetzt noch eine Kopie eines der Verzeichnisse mit richtigen Daten machen und ein paar Kommentare im Script nachrüsten.

Testlauf und Info dann aber sicher erst morgen Früh...

Ultrasparc - wo es kein *.vbs gibt
Bitte warten ..
Mitglied: Ultrasparc
15.08.2008 um 07:52 Uhr
So, da bin ich wieder.

Der Test mit den kopierten Live-Daten hat noch eine Kleinigkeit ergeben: Der Timestamp des Ordners wird nicht beachtet.

Beispiel: die Struktur wird durch Kopieren erzeugt, die Ordner bekommen also einen neuen Timestamp. Die Dateien nicht. Der Ordner (und die Files/Ordner in ihm) dürfen dann nur gelöscht werden, wenn auch der Ordner selbst entsprechend alt ist.

Es sollte ja auch 'DateLastModified' an dem zu prüfenden Unterordner geben, aber ich bekomme den nicht mal angezeigt (habe ich erwähnt, das ich kein VB kann?). Versucht habe ich es vor Zeile 20 - wenn er zu jung ist, braucht man ja gar nicht rein zu gehen.

Ultrasparc
Bitte warten ..
Mitglied: bastla
15.08.2008 um 10:05 Uhr
Hallo Ultrasparc!

Entsprechend Deinem Beispiel müsste dann aber bei Ordnern das Erstellungsdatum zum Kriterium gemacht werden - dazu die Zeilen 19-21 durch
01.
For Each Unter In Ordner.SubFolders 
02.
	L.WriteLine "## " & Heute - Int(Unter.DateCreated) & vbTab & Unter.Created & " """ & Unter.Path & """ ##" 
03.
	If Unter.DateCreated <= (Heute - Alter) Then 
04.
		DeleteInFolder(Unter) 
05.
	Else 
06.
		L.WriteLine "+++ """ & Unter.Path & """ wird nicht gelöscht. +++"		 
07.
	End If 
08.
Next
ersetzen.

Allerdings stellt sich mir die Frage, was einen neuen Ordner mit alten Daten erhaltenswert macht ...

Grüße
bastla
Bitte warten ..
Mitglied: Ultrasparc
15.08.2008 um 10:38 Uhr
Hallo bastla,

kann ich ganz leicht erklären. Das ist quasi eine Projekt-Struktur. Verschiedene Ordner werden nur gelesen, ohne geht es aber nicht.
Es hängt aber von den jeweiligen Änderungen ab, wo gelesen und wo geschrieben wird. Und wenn eine Datei in einem Ordner geändert wird, ändert sich ja das Datum des Ordners auch.

Ich glaube deshalb, das ein 'DateCreated' nicht das Passende ist.
Kann ich das einfach mit 'DateLastModified' ersetzen?

Ultrasparc
Bitte warten ..
Mitglied: bastla
15.08.2008 um 10:44 Uhr
Hallo Ultrasparc!

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
Bitte warten ..
Mitglied: Ultrasparc
15.08.2008 um 12:06 Uhr
Hallo bastla,

genau so soll es sein, das Löschen einer Datei ist eine Bearbeitung (der User macht da also noch was). Also nicht Löschen.
Ich versuche es noch mal anders darzustellen:
01.
startdir\dir1a\dir1b\dir1c\dat1 
02.
              \dir2b\dat2 
03.
              \dat3
Wenn unter dir1a etwas <= n ist (also dir1b, dir2b, dir1c, dat1, dat2 oder dat3 ), darf nichts unter dir1a gelöscht werden.

Leider hat das Einsetzen der Zeilen nicht zu einer Veränderung geführt. Keine der WriteLine Zeilen stehen im Logfile.

So sieht das jetzt aus:
01.
Sub DeleteInFolder(Ordner) 
02.
For Each Unter In Ordner.SubFolders 
03.
	L.WriteLine "#### " & Heute - Int(Unter.DateCreated) & vbTab & Unter.Created & " """ & Unter.Path & """ ####" 
04.
	If Unter.DateCreated <= (Heute - Alter) Then 
05.
		DeleteInFolder(Unter) 
06.
	Else 
07.
		L.WriteLine "++++ """ & Unter.Path & """ wird nicht gelöscht. ++++"		 
08.
	End If 
09.
Next 
10.
WegDamit = True 
11.
...
Habe ich was falsch gemacht?

Ultrasparc
Bitte warten ..
Mitglied: bastla
15.08.2008 um 13:05 Uhr
Hallo Ultrasparc!

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:
01.
	L.WriteLine "#### " & Heute - Int(Unter.DateLastModified) & vbTab & Unter.DateLastModified & " **" & Heute - Int(Unter.DateCreated) & "_" & Unter.DateCreated & "** """ & Unter.Path & """ ####" 
02.
	If Unter.DateCreated <= (Heute - Alter) And Unter.DateLastModified <= (Heute - Alter) Then
Grüße
bastla
Bitte warten ..
Mitglied: Ultrasparc
15.08.2008 um 15:36 Uhr
Hallo bastla,

ich habe das jetzt so weit korrigiert und am Laufen. Die Abfrage nach den Dateien ist auskommentiert. Meldungen kommen auch alle im Log.

Aber wenn ich Dich noch mal kurz in meinen letzten Beitrag bitten darf, der Absatz unter dem ersten Code - das geht eben nicht.
In dem Beispiel würde dir1c und dat1 gelöscht (wenn >= n), obwohl dir2b noch <= n ist. So soll es halt nicht sein.
Wahrscheinlich ist noch ein Art Level-Variable notwendig. Ich versuche mich da weiter.

Trotzdem vielen Dank, hast mir schon viel geholfen.

Ultrasparc
Bitte warten ..
Mitglied: bastla
15.08.2008 um 16:29 Uhr
Hallo Ultrasparc!

Soferne ich Dich jetzt (endlich) ganz richtig verstehe, hieße das ja eigentlich, es müssten im Fall des Falles immer nur die unmittelbaren Unterverzeichnisse des Startverzeichnisses gelöscht werden - richtig?

Grüße
bastla
Bitte warten ..
Mitglied: Ultrasparc
15.08.2008 um 17:31 Uhr
Hallo bastla,

ja, das ist absolut korrekt. Ich lasse damit zwar Sachen liegen, aber ich hätte einen mit at zu startenden Job, der mir nachts keinen Blödsinn macht.
Hast Du eine Idee, wie man so etwas umsetzt?

Für Sonderfälle kann ich ja per Hand auf ein Unterverzeichnis starten. Die User sind da sehr erfinderisch, was die Ablage von Daten angeht.


Ultrasparc
Bitte warten ..
Mitglied: bastla
15.08.2008 um 18:54 Uhr
Hallo Ultrasparc!

Da Du Dich als Batchfan deklariert hast, eine andere Version (mit gaaaanz wenig VBS ):
01.
@echo off & setlocal enabledelayedexpansion 
02.
set "Startverzeichnis=C:\Temp" 
03.
set Alter=10 
04.
 
05.
set S=%temp%\Stichtag.vbs 
06.
>%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) 
07.
for /f %%i in ('cscript //nologo %S% -%Alter%') do set "Stichtag=%%i" 
08.
if not defined Stichtag echo Fehler bei Tageberechnung & goto :eof 
09.
 
10.
echo Stichtag:  %Stichtag%  bei Alter:  %Alter% 
11.
echo\ 
12.
for /d %%i in ("%Startverzeichnis%\*.*") do call :Verzeichnis "%%i" 
13.
goto :eof 
14.
 
15.
:Verzeichnis 
16.
echo ==================================================================== 
17.
set Behalten= 
18.
echo  %~t1 %1 
19.
for /f "tokens=1-3 delims=. " %%a in ("%~t1") do if %%c%%b%%a geq %Stichtag% set Behalten=True & goto :VerzeichnisFertig 
20.
for /f %%f in ('dir /s /b /ad %1') do if not defined Behalten ( 
21.
    if "%%~tf" neq "" ( 
22.
	    echo  %%~tf "%%f" 
23.
	    for /f "tokens=1-3 delims=. " %%a in ("%%~tf") do if %%c%%b%%a geq %Stichtag% set Behalten=True 
24.
		) else ( 
25.
	    set "Parent=%%~dpf" 
26.
		for /f "tokens=1-3 delims=. " %%a in ('dir /tc /ad "!Parent!"^|findstr /e c:"%%nxf"') do ( 
27.
            echo  %%a.%%b.%%c "%%f" 
28.
			if %%c%%b%%a geq %Stichtag% set Behalten=True 
29.
30.
31.
32.
:VerzeichnisFertig 
33.
if not defined Behalten goto :WegDamit 
34.
echo -------------------------------------------------------------------- 
35.
echo ++++ %1 wird nicht entfernt. ++++ 
36.
echo ==================================================================== 
37.
echo\ 
38.
goto :eof 
39.
 
40.
:WegDamit 
41.
echo -------------------------------------------------------------------- 
42.
echo #### %1 wird entfernt. #### 
43.
echo ==================================================================== 
44.
echo\ 
45.
::rd /s /q %1 
46.
goto :eof
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
Bitte warten ..
Mitglied: Ultrasparc
15.08.2008 um 20:04 Uhr
Hallo bastla,

bei Batch muss ich nicht so viele dumme Fragen stellen - stimmt, aber wenn ich dann hier immer sehe, wie die Zeilen aus dem Ärmel geschüttelt werden - Hut ab.
Auch wenn ich etwas ähnliches zustande gebracht habe, bei der Rechnerei mit den Zeiten habe ich mich verrannt. Von der Zeit, die ich gebraucht habe mal ganz abgesehen.

Ich danke wieder für die uneigenützige Hilfe, am Montag hänge ich mich wieder ran.
Schönes Wochenende.

Ultrasparc
Bitte warten ..
Mitglied: Ultrasparc
18.08.2008 um 16:09 Uhr
Hallo bastla,

da bin ich wieder.
Was mir beim Lesen gleich augefallen ist: kleiner Fehler in Zeile 2 - da ist das Hochkomma verutscht, richtig wäre natürlich
01.
set Startverzeichnis="C:\Temp"
Falls jemand mitliest.
...
So, die letzten Zeilen stammen von 6:20, bis jetzt gab es immer Wichtigeres zu tun. Aber jetzt.
Es tut, prima. Habe zwei Verzeichnisse gesäubert. Nur kleine Optimierungen wie z.B. Löschen von Leeren Ordner, auch wenn sie noch zu jung sind. Und schreiben in ein Log und so Sachen.

Nochmals vielen Dank.

Ultrasparc
Bitte warten ..
Mitglied: bastla
18.08.2008 um 16:15 Uhr
Hallo Ultrasparc!

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
Bitte warten ..
Mitglied: Ultrasparc
18.08.2008 um 17:59 Uhr
ok, merke ich mir...

Ultrasparc
Bitte warten ..
Neuester Wissensbeitrag
Windows 10

Powershell 5 BSOD

(1)

Tipp von agowa338 zum Thema Windows 10 ...

Ähnliche Inhalte
Batch & Shell
gelöst älteste dateien via batch löschen (6)

Frage von cali169 zum Thema Batch & Shell ...

Entwicklung
Versteckte .(Punkt)Dateien löschen (3)

Frage von DarkJM zum Thema Entwicklung ...

Batch & Shell
14 Tage alte Dateien automatisch löschen - Shell (1)

Frage von traller zum Thema Batch & Shell ...

Heiß diskutierte Inhalte
LAN, WAN, Wireless
gelöst Server erkennt Client nicht wenn er ausserhalb des DHCP Pools liegt (28)

Frage von Mar-west zum Thema LAN, WAN, Wireless ...

Outlook & Mail
Outlook 2010 findet ost datei nicht (18)

Frage von Floh21 zum Thema Outlook & Mail ...

Windows Server
Server 2008R2 startet nicht mehr (Bad Patch 0xa) (18)

Frage von Haures zum Thema Windows Server ...