domonomie
Goto Top

bestimmten Ordner per Batch-Datei löschen

Hallo Admins,
hab da mal wieder so ein kleines Batch-Problem.

Mein Server sichert jeden Tag die wichtigsten Dateien meiner Clients per Batch-Datei. Zusätzlich einmal im Monat komplett.
Bei jeder Sicherung legt er automatisch einen Ordner mit dem Datum der Sicherung an.
z.B: Sicherung\AVAWIN\Do 18.08.2005

Nach ner Woche habe ich dann also 7 Ordner (ich weiß am Wochende wird nix gearbeitetface-smile egal, dient ja nur der verdeutlichung).

Nun möchte ich bei der 8ten Sicherung automatisch die älteste Sicherung löschen lassen.

Bin langsam am verzweifeln. Wie mache ich das über eine Batch-Datei?
Ich probiere schon als mit IF & ELSE rum, bringt aber nix.

Also nochmal kurz:

überprüfen wieviel Ordner vorhanden sind -----> ist die Anzahl der Ordner > 7 dann lösche den ältesten Ordner

Ich hoffe das ist verständlich genug gewesen.
Danke schonmal für die Hilfe


Gruß
Domonomie

Content-ID: 14605

Url: https://administrator.de/contentid/14605

Ausgedruckt am: 23.11.2024 um 00:11 Uhr

Biber
Biber 19.08.2005 um 07:30:22 Uhr
Goto Top
Moin domonomie,
ich hatte neulich mal einen ähnlichen Lösungsvorschlag gepostet beim Thread Batch Sichern der 10 zuletzt geänderten Dateien".
Wenn ich die damalige Lösung schnell quick & dirty anpasse, erhalte ich folgende Skizze:
::-------snipp DelOldBackupQuicknDirty.bat
@echo off 
(set /a MaxDirs=4) &  (set /a counter=0)
:: hab keine 8 Verzeichnisse; 4 ist nur Test-Beispiel 
@echo MaxDirs=%MaxDirs%
for /f "delims=" %%i in ('dir /Ad /b /o:<blubb>-D "?? ??.??.200?"') do call :loop "%%i"   
goto :eof 
:loop 
set /a counter=%Counter%+1
if %counter% LEQ %MaxDirs% (echo %~1 ...%Counter% ^<^= %MaxDirs%....ok, kann bleiben) & goto :eof
echo %~1 ...%Counter% ^>  %MaxDirs% ...hau ich wech mit RD *gg 
goto :eof
::-------snapp DelOldBackupQuicknDirty.bat
...und beim Test folgenden Output (die linke Spalte sind Deine Verzeichnisse!!)
D:\temp\avawin>
>DelOldBackupQuicknDirty.bat
MaxDirs=4
So 21.08.2005 ...1 <= 4....ok, kann bleiben
Sa 20.08.2005 ...2 <= 4....ok, kann bleiben
Fr 19.08.2005 ...3 <= 4....ok, kann bleiben
Do 18.08.2005 ...4 <= 4....ok, kann bleiben
Mi 17.08.2005 ...5 >  4 ....hau ich wech mit RD *gg
Di 16.08.2005 ...6 >  4 ....hau ich wech mit RD *gg
Mo 15.08.2005 ...7 >  4 ....hau ich wech mit RD *gg
Aber, wie geschrieben, das ist eine Hau-Ruck-Lösung, damit würde ich nicht produktiv gehen. Denn die Skizze hat keine Pfadangabe, keine Logdatei, keinerlei Fehlerbehandlung, keinerlei Parameter, die es etwas flexibler machen.
Wart noch ein paar Tage, dann poste ich mal eine etwas allgemeinere Lösung, die auch andere Kriterien als Anzahl Sicherungen=7 und Deine Dateimaske erlaubt.
Oder ich mach das wieder im Batch-Workshop als Tutorial face-smile

HTH Frank / der Biber aus Bremen
domonomie
domonomie 19.08.2005 um 17:37:52 Uhr
Goto Top
Danke für die rasche Antwort.
Das sieht schon mal genau danach aus, wonach ich suche. Ich werde gleich mal probieren ob ich da durchblicke. Nehme deinen anderen Thread zur Hilfe.
Wäre super wenn du mir das noch etwas anpassen könntest.

Gruß
Dominique
Biber
Biber 19.08.2005 um 18:16:43 Uhr
Goto Top
Moin, Dominique,
im Prinzip ja...
wie wir Computerfuzzies immer so gerne sagen, aber...

Wie oben angedeutet, meine Strategie wäre natürlich eher, einen robusten und flexiblen Batch zu haben, der wenigstens die Anforderungen der beiden Threads erfüllen kann statt 2 Bätche für zwei so ähnliche Aufgaben. Also lieber einen Batch, der
- sowohl Dateien wie Ordner handelt
- diverse Kriterien als Parameter annimmt (Dateimaske, Pfade, SicherungsDatums-/SicherungsAnzahls-Werte)
- ein paar Log & Alarm-Optionen hat, damit er auch unbeaufsichtigt als Dienst laufen kann und mich nur belästigt, wenn er mal auf Fehler läuft. Und sonst nur brav *.Log-Einträge schreibt. (Von denen er dann selbst wieder die ältesten löscht face-smile ...)

Aber wie ich mich kenne, wird der wieder 30 oder 40 Zeilen lang und ist dann schon eher was für ein Tutorial...
Aber schreib doch bitte, was so ein Batch bei Dir alles können müsste.
Bau ich gerne ein.

Frank / der Biber aus Bremen
domonomie
domonomie 19.08.2005 um 21:47:29 Uhr
Goto Top
Die Batch muss nicht viel können. Wie schon gesagt. Nur einlesen wieviele Sicherungen sprich Ordner schon vorhanden sind und den ältesten davon löschen. die letzten 3 sicherungen möchte ich aber z.B behalten.

->----------------------------------------------------------------<-
Ordner: Sicherung Mo 15.08.2005
Ordner: Sicherung Di 16.08.2005
Ordner: Sicherung Mi 17.08.2005
Ordner: Sicherung Do 18.08.2005
> jetzt möchte ich ne Batch aufrufen, die mir den ältesten (die ältesen bei mehr als 4 ordnern) Ordner löscht
> die vorherige Batch ruft dann meine schon seit Ewigkeiten laufende Sicherungs-Batch auf

am Ende habe ich dann wieder 4 Ordner: die aktuelle Sicherung + die 3 Vorgänger
domonomie
domonomie 19.08.2005 um 22:19:43 Uhr
Goto Top
Hi Biber,
mir ist aufgefallen, dass deine Batch nach dem Erstellungsdatum sortiert. Wenn ich aber jetzt willkürlich Ordner erstelle und die Batch laufen lasse, dann löscht der mir zwar den Ordner, den ich zuerst erstellt habe, dieser ist aber nicht immer der richtige.

Erstelle ich die Ordner nacheinander mit fortlaufendem Datum, dann gehts. Ändere ich einen, dann scheiterts.

Die Batch sollte also nach dem Ordnernamen gucken, nicht nach dem Erstellungsdatum.

ansonsten funktioniert deine Lösung einwandfrei
Biber
Biber 19.08.2005 um 22:58:34 Uhr
Goto Top
Ist notiert, domonimie,
sind zwei wichtige Hinweise für einen allgemein verwendbaren Batch, allerdings...
...in Deinem konkreten Fall wird es schwierig, fürchte ich *Kopfkratz*....
Was ich meine, ist: ich kann mir ein Szenario vorstellen, in dem Ordner irgendwann angelegt und irgendwann später mit neuen Inhalten vorsehen werden. Konstruiertes Beispiel: eine Ordnerstruktur der Form
..
SicherungKW33
SicherungKW34
SicherungKW36
..
die Jahr für Jahr neu mit Sicherungen neu befüllt wird.

oder eine 10-Ordner-Ringlösung der Form Tagessicherung in Ordner Backup01 bis Backup10 und wieder von vorn. In beiden Fällen nützt mir das Erstellungdatum des Ordners wenig. Sondern da wäre als (machbarer) Zwischenschritt denkbar "Ermittle aus jedem SicherungKW**- bzw Backup*-Ordner das jüngste Datum und lösche dann die Ordner mit dem ältesten jüngsten Datum" (ich sehr gut Deutsch sprechen, ich allein gelernt). (Wäre Deine erste nützliche Anregung für Erweiterungen).

Der zweite implizite Tipp ist natürlich, dass ich in diesem Fall auch die Ordner gar nicht weglöschen darf, sondern nur deren Inhalte.

Aber zurück zu Deinem konkreten Problemchen... irgendwie sortieren können sollte ich ich die Ordner programmtechnisch schon... wie ist denn die programmatisch richtige Sortierung Deiner Ordnerstruktur:
Mo 15.08.2005
Di 16.08.2005
Mi 17.08.2005
Do 18.08.2005
Fr 19.08.2005
Sa 20.08.2005
So 21.08.2005....??
*grübel... obwohl...doch, geht vielleicht doch..

Mal sehen, wenn es nicht mehr als drei Zusatzzeilen erfordert, bau ich das ein.
Aber einfacher wäre das Leben schon, wenn ihr das Datum z.B. ANSI-ähnlich als Ordnername vergeben würdet:
2005-08-15Mo
2005-08-16Di
2005-08-17Mi
2005-08-18Do ....etc

Ich bastel mal beim nächsten Regentag,
Schöne Vollmondnacht Dir und allen ein schönes Wochenende wünscht
Biber
domonomie
domonomie 28.08.2005 um 13:41:40 Uhr
Goto Top
Hallo Biber,
Bin jetzt wieder an der Batch-Datei dran.
Ich kann eigentlich damit leben, dass der nach dem Erstellungsdatum guckt.
Habe es jetzt vor und zurück probiert (immer das Systemdatum um einen Tag weiter gestellt) und deine Batch macht genau das, was sie machen soll.

Jetzt erklär mir aber mal bitte, wie und wo ich den "rd /s /q"-Befehl hinsetzen muss. Ich lösche mir dummerweise immer alle Ordner face-smile

Der RD-Befehl muss doch in diese Zeile oder? Nur wo (klar an Stelle von echo, und weiter??)

echo %~1 ...%Counter% ^> %MaxDirs% ...hau ich wech mit RD *gg

Danke schonmal.
Dominique
Biber
Biber 28.08.2005 um 21:35:22 Uhr
Goto Top
Hallo domonomie,

genau, statt der zweiten echo-Zeile oben..
echo %~1 ...%Counter% ^> %MaxDirs% ...hau ich wech mit RD *gg
die Zeile
rd /s /q %1
also statt %~1 diesmal den Parameter "Verzeichnisname" MIT Anfü-zeichen.
Wird somit aufgelöst als Zeile rd /s /q "Mi 17.08.2005" usw. usw.
Lass den Batch erstmal mit den Testzeilen
@echo rd /s /q %1
pause

laufen oder mit rd /s %1 OHNE den Parameter "/q".
Wenn das läuft, wie es soll, dann die "richtige" Zeile rd /s /q %1 scharfmachen.
HTH Biber

[edit]
...vorausgesetzt, Du rufst den Batch aus dem Parent-Verzeichnis der Archivverzeichnisse auf, also da, wo im Moment auch der Dir-Befehl klappt.
Sonst musst du statt Parameter %i den Parameter %~dpi nehmen (Drive und Path mit anhängen) [/edit]
thalys
thalys 25.08.2006 um 14:50:14 Uhr
Goto Top
Jetzt häng ich mich hier auch noch schnell rein, da ich selber von Batch-Programmierung keinen Schimmer habe, die Aufgabe aber wohl eher simpler Natur ist.

Also, ich würde gerne alle Ordner (Win XP Pro) unter "Dokumente und Einstellungen" (also die Benutzerprofile) löschen, BIS AUF einige von mir definierte Verzeichnisse!
Das sollen z.B. Administrator, DefaultUser, AllUsers und ein weiteres Konto sein, ich nenns ich mal User1.

Kann mir dazu mal gerade jemand die nötigen Zeilen aus dem Handgelenk schütteln? Ein Tool um diese Batch-datei mit Adminrechten zu starten hab ich schon....

Danke sehr!
Biber
Biber 27.08.2006 um 14:18:53 Uhr
Goto Top
Moin thalys,

willkommen im Forum.

Ganz so trivial ist Deine Frage nicht - zumindest nicht für eine allgemein verwendbare Lösung. Je nachdem, wie das Ziel Deiner Anforderung spezifiziert wir, tunsich schon ein paar Stolpersteine auf.

Lass mich mal rantasten.

Wenn das Ziel ist, bestimmte namentlich bekannte Userprofile zu löschen, dann bräuchtest Du einen Batchjob namens
DelUserProfile.bat Para1:profilename1 [Para2:profilename2][Para3:...]

Wenn das sinnvolle Vorgehen wäre, pauschal nur bestimmte namentlich bekannte Userprofile zu erhalten, dann brauchst Du einen Batch namens
DelAllVarUserprofilesBut.bat Para1:NotToDeleteProfile1 [Para2:NotToDeleteProfile2]....
, der fest verdrahtet alle Standard-Profile ("Default User","All Users",..) stehen lässt und ebenfalls die als Parameter angegebenen Userprofie... und blind alles andere plattmacht.

Ein erstes Forechecking am CMD-Prompt zeigt, dass die zweite Variante definitiv zu risikoreich ist aus zwei Gründen.
Ich kann zwar den Speicherort meines eigenen Userprofils herausfinden über die Umgebungsvariable %USERPROFILE%, aber
a) ich kann nur vermuten, dass alle anderen Userprofile parallel zu meinem Userprofil gespeichert werden
b) ich kann nicht sicher sein, dass alle Unterverzeichnis-Strukturen auf der Ebene "MeinUserProfil" ebenfalls Userprofile sind.

Ich zeig mal, was ich meine:
>for /f "delims=" %i in ('dir /a:d /b "%userprofile%\..\."') do @echo "%userprofile%\..\%i" 
"C:\Dokumente und Einstellungen\Biber@Home\..\Default User" 
"C:\Dokumente und Einstellungen\Biber@Home\..\All Users" 
"C:\Dokumente und Einstellungen\Biber@Home\..\NetworkService"       -->kein Userprofil !!! 
"C:\Dokumente und Einstellungen\Biber@Home\..\LocalService"          ---> kein Userprofil !!! 
"C:\Dokumente und Einstellungen\Biber@Home\..\Biber@Home" 
"C:\Dokumente und Einstellungen\Biber@Home\..\TEMP"                     --> keine Ahnung...heißt der User "TEMP" ??? 

Wenn ich hier einen Batch abgefeuert hätte mit dem Algorithmus "Lösche alle Verzeichnisse dieser Ebene außer All Users, Default User und meinem eigenen Biber@Home", dann wär es ins Auge gegangen- ich hätte Nicht-Userprofile gelöscht.

Also doch die Positiv-Variante einer Aufzählung DelUserProfile.bat Para1:profilename1 [Para2:profilename2][Para3:...]? Auch blöd. Dann müsste ich alle "überflüssigen" Userprofile mit Vor- und Nachnamen kennen...

Kompromiss wäre ein Batch, der interaktiv arbeitet, also bei jedem Userprofil-Namen, der potentiell wegzulöschen wäre, noch einmal nachfragt, ob der wirklich gelöscht werden kann.
Also variieren wir diese Strategie....
>for /f "delims=" %i in ('dir /a:d /b "%userprofile%\..\."') do rd /s /q "%userprofile%\..\%i"  
rd /s /y "C:\Dokumente und Einstellungen\Biber@Home\..\Default User"  
rd /s /y "C:\Dokumente und Einstellungen\Biber@Home\..\All Users"  
rd /s /y "C:\Dokumente und Einstellungen\Biber@Home\..\NetworkService"  
rd /s /y "C:\Dokumente und Einstellungen\Biber@Home\..\LocalService"  
rd /s /y "C:\Dokumente und Einstellungen\Biber@Home\..\Biber@Home"  
rd /s /y "C:\Dokumente und Einstellungen\Biber@Home\..\TEMP"  

... in einem Batch in diese Art:
::-----DelAllNonStandardProfiles.bat
@echo off & setlocal
for /f "delims=" %%i in ('dir /a:d /b "%userprofile%\..\."') do call :Ask4Deletion "%%i"  
goto :eof

:Ask4Deletion [Parameter1=Verzeichnisname]
REM Step 1 ..."bekannte" Standardverzeichnisse NICHT löschen. Mein eigenes auch nicht!  
for %%a in ("Default User", "All Users", "NetworkService", "LocalService", "Biber@Home") do if /i [%%a]==[%1] goto :eof  
REM Step 2 Sicherheitsabfrage zulassen, KEIN Parameter "/Q" !!! (es sei denn, auf eigene Gefahr)   
rd /s  "%userprofile%\..\%~1"  
goto :eof
::----- snapp DelAllNonStandardProfiles.bat [ungetestete Skizze]

So in etwa wären Vorüberlegungen und Techniken.
Je nachdem, ob Du es nur auf Deinem eigenen Rechner einsetzen willst, den Du ja kennst wie Deine Westentasche, oder ob das ein Standard-Utility für die ganze Domäne werden soll, kannst Du vorsichtiger oder radikaler vorgehen bei Deinen Anpassungen.

Hope That Helps
Biber
P.S. Ansonsten würde ich diesen Thread gerne ganz schließen und Dich bitten, ggf. einen neuen aufzumachen.
netsaver
netsaver 17.03.2007 um 20:26:52 Uhr
Goto Top
Hallo,

ich bin per Google in diesem Thread gelandet.

Könntet ihr vielleicht den kompletten Quelltext der Batchdatei mal hier einstellen?
Bei mir bricht beim "for /f "delims=" %%i in ('dir /Ad /b /o:<blubb>-D "?? ??.??.200?"') do call :loop "%%i"" ab.

Vielen Dank.

LG; Thomas
Biber
Biber 18.03.2007 um 19:10:03 Uhr
Goto Top
Moin netsaver,

der Sourcecode steht oben... also hat es wahrscheinlich mit Anpassungen an Deine Gegebenheiten (Pfadnamen, Ordnernamen-Konventionen...) zu tun.

Meine Bitte - poste hier oder in einem neuen Thread in Batch und Shell den bisherigen bei Dir fehlerwerfenden Code und lass uns dann davon ausgehen bei der Fehlersuche.

Gruss
Biber
netsaver
netsaver 18.03.2007 um 19:39:23 Uhr
Goto Top
Hi Biber, ich denke es hat sich schon erledigt. Hat zwar ne halbe Nacht gedauert aber... face-wink

Ich hab mir mal mein eigenes Komplett-Backup-Skript gebastelt:

set jahr=%date:~-4%
set monat=%date:~-7,2%
set tag=%date:~-10,2%

@echo . >>%Ziel%\backup.log

:: DEFINITIONEN

set Quelle="C:\Dokumente und Einstellungen\Thomas\Desktop\THOMAS"  
::set Zielordner="%LocalDrive%\_BACKUP\THOMAS\" 
set Zielordner="K:\_BACKUP\THOMAS\"  

set Ziel=%Zielordner%\%jahr%%monat%%tag%
set templog="%temp%\temp.log"  


::RESET ARCHIV BIT

@echo %tag% 

@echo
if %tag%==7 attrib +A /d /s %Quelle%*.*
if %tag%==14 attrib +A /d /s %Quelle%*.*
if %tag%==21 attrib +A /d /s %Quelle%*.*
if %tag%==28 attrib +A /d /s %Quelle%*.*
else goto :eof


:: SICHERE DATEN

md %Ziel%
echo . >>%Ziel%\backup.log
echo Starte Backup: %date% %time% von %Quelle% nach %Ziel% >>%Ziel%\backup.log
xcopy %Quelle% %Ziel% /m /s /v /c /i /f /h /k /o /x /y >>%Ziel%\backup.log
echo Fertig >>%Ziel%\backup.log


@echo :: ALTE SICHERUNGEN LÖSCHEN 
(set /a MaxDirs=14) & (set /a counter=0)
@echo MaxDirs=%MaxDirs%
for /f "delims=" %%i in ('dir /Ad /A-h /b /O-N "%Zielordner%"') do call :loop "%%i"  
goto :eof


:loop
set /a counter=%Counter%+1 >>%Ziel%\backup.log
if %counter% LEQ %MaxDirs% (echo %~1 ...%Counter% ^<^= %MaxDirs%....ok, kann bleiben) & goto :eof >>%Ziel%\backup.log

@echo BACKUP BEENDET!
rd /s /q %~1 >>%Ziel%\backup.log
goto :eof

Ich prüfe ob es Zeit für ein Voll-Backup ist.
-> ja -> setze archivbit auf alle dateien -> dann weiter
-> nein ->weiter

Dann sichere ich den Ordner "Thomas" auf dem Desktop

Dann schau ich (Danke für den Code) wie viele Sicherungen es im Backup-Verzeichnis gibt und löscht die älteste.

LG;

PS: Ich bin echt mies im Batch Skripten, wenn also jemand Verbesserungsvorschläge hat: Her damit, bin immer dankbar face-wink

PPS: ich habe noch ein direktes Problem:
Wie kann ich dem Skript zum Ordner löschen den Pfad zum Ziellaufwerk / Pfad unterschieben? Wenn ich ihm direkt %Ziellaufwerk% gebe dann löscht er dem ganzen Ordner "K:\_BACKUP\THOMAS"
Momentan muss ich das Skript im Backup-Verzeichnis ablegen (wegen %~1, ich weiss) das will ich aber nicht..

rd /s /q "K:\_BACKUP\THOMAS" <- löscht alles... wie mache ichs richtig? LG;
Biber
Biber 19.03.2007 um 08:22:48 Uhr
Goto Top
Moin netsaver,

PPS: ich habe noch ein direktes Problem:
Wie kann ich dem Skript zum Ordner löschen den Pfad zum Ziellaufwerk / Pfad
unterschieben? Wenn ich ihm direkt %Ziellaufwerk% gebe dann löscht er dem ganzen
Ordner "K:\_BACKUP\THOMAS"
Momentan muss ich das Skript im Backup-Verzeichnis ablegen (wegen %~1, ich weiss)
das will ich aber nicht..
Mussst Du auch nicht. Die "%~1" bezieht sich auf den Parameter 1 des geCALLten Blocks ":loop", nicht auf den Parameter 1 des ganzen Batches oder so.
Das Skript kann sonstwo liegen (z.B. im %path% in %windir%\system32

rd /s /q "K:\_BACKUP\THOMAS" <- löscht alles... wie mache ichs richtig?
Sollte so reichen:
@echo BACKUP BEENDET!
rd /s /q "%zielordner%\%~1" >>%Ziel%\backup.log
P.S. Dieses hier: "@echo . >>%Ziel%\backup.log" kommt zu einem Zeitpunkt VOR der definition von %ziel%. Wird nicht klappen.

Gruss
Biber