Batch Benötige Rat bei Batch - DEL soll bestimmten Unterordner ignorieren.

Jossy82

Lieutenant
Registriert
Aug. 2009
Beiträge
528
Ich will in einem "mobilen" Ordner mit mehreren Unterordnern verschiedene config Dateien mit der Endung *.cfg löschen.
Dabei soll aber der Unterordner specialfolder und alle weiteren dort noch verschachtelten Unterordner ausgenommen werden.

Der Code soll in eine bestehende Batch mit aufgenommen werden um den Funktionsumfang zu erweitern und gleichzeitig übersichtlicher zu machen. (Bisher jeden Unterordner einzeln aufgeführt, zudem müssen neue Ordner manuell nachgetragen werden.)

Ich habe es mit folgenden Codeschnippseln aus dem Netz versucht - wobei mir durchaus hier und da wohl einfach der Durchblick fehlt:

/////////////////////////////////////////////////////////////////////////////////////

Bester Ansatz denke ich war, auch wenn es nicht läuft:


@Echo off
set root=d:/document and settings <----- Bei mir: set root=%CD%

for /F "usebackq" %%i in (dir /b "%root%") do ( set flag=0

REM here you must make a block for every folder you dont want to change
REM START OF EXCLUSION LIST
if /i "%%i"=="Appdata" (set flag=1) <----- Bei mir einmal: if /i "%%i"=="specialfolder" (set flag=1)
if /i "%%i"=="default" (set flag=1)
if /i "%%i"=="public" (set flag=1)
REM END OF EXCLUSION LIST

call :delete %%i )

pause
exit /b 0

:delete
if "%flag%"=="0" ( echo Processing: %1
REM here you can delete whatever you want. <------ Keine Ahnung ob ich hier direkt folgendes setzten kann: del /q /f ".cfg
REM the current folder is: %root%\%1 )

goto :eof

/////////////////////////////////////////////////////////////////////////////////////

Weitere Ansätze, die ich noch nicht probiert habe wären (Muss ich wirklich den root setzen wenn ich doch bereits %CD% oder ./ nutzen kann?):


@Echo off
::type the root folder where the "find and delete folder" will run
SET WhereTolook=C:\Admin\testfolder
::What to exclude?
SET ExcludeWhat=%WhereTolook%\MASTER
::then we will search the folder and all its subfolders and pipe | that output to "FINDSTR" command that find everything except the folder you want to exclude then we RD(remove folders) and sub folders
FOR /F "delims=*" %%G IN ('dir "%WhereTolook%" /B /S /AD ^| findstr /v "%ExcludeWhat%"') DO RD "%%G" /Q /S
::If there are any files in the root directory you want to remove
del %WhereTolook% /q

/////////////////////////////////////////////////////////////////////////////////////

@Echo OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "keepfile=1.bat"
SET "keepdir=keep me"

FOR /d %%a IN ("%sourcedir%\*") DO IF /i NOT "%%~nxa"=="%keepdir%" RD /S /Q "%%a"
FOR %%a IN ("%sourcedir%\*") DO IF /i NOT "%%~nxa"=="%keepfile%" DEL "%%a"

GOTO :EOF

/////////////////////////////////////////////////////////////////////////////////////


Ich bin gut ins Schwimmen geraten und habe den Überblick verloren, kann mir jemand aushelfen?
 
Bin gerade nur am Handy und kann leider nix konkretes beisteuern, aber eine Idee einstreuen.

Wenn du mit dir /s /b *.cfg machst, müsstest du alle cfg-Dateien inkl. Pfad als Liste bekommen, wenn ich mich nicht irre. Diesen Pfad prüfst du darauf ob der fragliche Ordnername darin auftaucht und ignorierst diese Datei, löschst aber alle Dateien wo er nicht vorkommt.
Sollte der dir-Befehl selbst entgegen meiner Erinnerung nicht die geforderte Liste liefern, kann man natürlich auch mittels for durch die Files laufen und dort den Pfad auf den Ordner prüfen.

Eine ganz andere Idee wäre es, den fraglichen Ordner vorher zu sichern, also wegzukopieren, danach alles löschen und das Backup wieder reinkopieren.

Wenn du damit nicht weiterkommst, kann ich mal ein bischen basteln, wenn ich wieder an einem PC sitze, tendentiell aber erst gegen Sonntag.
 
attrib +r d:\temp\specialfolder\*.cfg /s del d:\temp\*.cfg /s /q attrib -r d:\temp\specialfolder\*.cfg /s
 
  • Gefällt mir
Reaktionen: Raijin
Danke Jenny! Und Dir auch Raijin!

Code:
attrib +r .\specialfolder\*.cfg /s
del .\*.cfg /s /q
attrib -r .\specialfolder\*.cfg /s

Hats im Testlauf geregelt, ich bastel dass jetzt mal in meine eigentlich Batch.

Nachtrag:
In der Batch läuft es auch! Danke nochmal!

Nun muss ich noch den umgekehrten Weg rausfinden: aus dem Specialfolder\spezifischerunterordner die *.cfg in die Unterordner kopieren ohne dass er auf .\ kopiert... Er soll nur in die Unterordner der ersten Schicht, nicht aber noch weiter tiefere und auch nicht ins "root-Verzeichnis" kopieren.

Das wird nochmal ein anderes Fass, vermutlich Liste mit den subfoldern erstellen, durch Filter am Kommando gleich bereinigen lassen und mit FOR durchkopieren.... :D
Ergänzung ()

Jetzt frage ich mich warum
Code:
attrib +r .\specialfolder\*.cfg /s
del .\*.cfg /s /q
attrib -r .\specialfolder\*.cfg /s
geht aber nicht
Code:
attrib +r %CD%\specialfolder\*.cfg /s
del %CD%\*.cfg /s /q
attrib -r %CD%\specialfolder\*.cfg /s

%CD% für "current working folder" nimmt er in der batch doch auch ansonsten überall...

Edit:
Anführungszeichen... Das fehlte, mit %CD% geht es dann auch...

Code:
attrib +r "%CD%\specialfolder\*.cfg" /s
del "%CD%\*.cfg" /s /q
attrib -r "%CD%\specialfolder\*.cfg" /s
Ergänzung ()

Letzter Nachtrag: Auch der umgekehrte Weg ging nach etwas Recherche und Recycling bereits vorhandenen codes. Er kopiert aus dem specialfolder/unterordner die*.cfg in die gewünschten unterordner:

Code:
set cfg=qw (Nur für den Testlauf, das wird in der Batch dann woanders geregelt.)
dir /b /ad >>ed1.txt
type ed1.txt | findstr /v specialfolder >>cfgreset.txt
for /f "tokens=*" %%Q in (cfgreset.txt) do xcopy /f /y "%CD%\specialfolder\config\%cfg%\%cfgf%" "%CD%\%%Q"
del /q "%CD%\ed1.txt"
del /q "%CD%\cfgreset.txt"
 
Zuletzt bearbeitet:
Batch ist tot. Nimm Powershell.

Dort dann:
PowerShell:
Get-Childitem -Path wo-die-Daten-liegen -Exclude der-pfad-wo-nicht-reingeguckt-werden-soll -Recurse -Filter '*.cfg' |
Remove-Item -Verbose -WhatIf
Wenn das so nicht funktionieren will:
PowerShell:
Get-Childitem -Path wo-die-Daten-liegen  -Recurse -Filter '*.cfg' |
Where-Object { $_.Fullname -notlike "C:\pfad\exclude\*" } |
Remove-Item -Verbose -WhatIf

Wenn es nur um ein Fragment in einer bestehenden Batch geht, dann kann man diesen Teil auch in ein PS1 Script packen und das aus Batch heraus mit Powershell -Exec bypass -File "Pfad zur PS1 Datei" ausführen lassen.

Note: Das -Whatif da oben soll übereifriges copypasta ein bißchen einschränken helfen. Es muß weg, damit die Dateien auch wirklich gelöscht werden, kann/soll aber solange bleiben bis auch wirklich die richtigen Daten zum löschen gefunden werden.
 
Zurück
Oben