Leere Ordner, die ein bestimmtes Wort NICHT beinhalten, verschieben bzw. löschen
ich stehe vor einem problem, für das ich selbst keine lösung finden kann. ich hab eine größere Menge von Ordnern, in denen sich dateien und auch immer eine prüfsummendatei befinden, über einen server auf eine andere platte verschoben. der server hat dabei per script die prüfsummen verglichen und nur diejenigen dateien durchgelassen, die den check bestanden haben. wenn ein ordnerinhalt den test nicht bestand, wurde der ordner jedoch auf der neuen platte erstellt und ist nun entweder leer oder beinhaltet dateien, die nicht in der prüfsumme enthalten sind. vollständige ordner wurden auf der zielplatte mit einem zusätzlichen "header"-ordner versehen, der im namen zusätzlich das wort "complete" beinhaltet.
ich suche jetzt nach einer möglichkeit, über der zielplatte mit einem script zu iterieren und alle ordner, die leer sind und nicht das wort "complete" oder "incomplete" beinhalten, in einen sammelordner zu verschieben, um das löschen manuell vorzunehmen und so nochmal eine letzte sicherheitsschranke gegen versehentliches löschen falscher ordner einzubauen.
ich suche nun schon tagelang nach einem guten tut für ein batch-script oder vbs. aber ich komme nicht voran, weil ich bislang programmiertechnisch nur über dateien iteriert habe und die syntax der batch scripte nicht so wirklich verstehe. zwar gibt es den befehl if exist und die option des stringvergleiches, aber irgendwie krieg ich das nicht so zusammengebaut, dass die ordnernamen darauf geprüft werden, ob sie diese begriffe nicht enthalten.
hat vielleicht jemand eine idee, wie man da rangehen könnte oder gar schonmal sowas geschrieben?
ich wäre wirklich super dankbar für hilfe.
mfg
clubnite
Content-Key: 76735
Url: https://administrator.de/contentid/76735
Ausgedruckt am: 28.03.2024 um 16:03 Uhr
@echo off
::Eventuell existierende Logfiles ins Jenseits befördern
if exist %systemroot%\temp\delbatch (
rmdir /s /q %systemroot%\temp\delbatch
)
::Ordner für Logfiles erstellen
mkdir %systemroot%\temp\delbatch
:: Alle Ordner herausfiltern, die das Wort "Complete" nicht enthalten
dir <Pfad zu deinem Ordner> /s /b /a:d | find /v /i "complete" >%systemroot%\temp\delbatch\step1.txt
::Aus dem 2. Logfile alle Ordner herausfiltern, die das Wort "Incomplete" nicht enthalten
dir <Pfad zu deinem Ordner> /s /b /a:d | find /v /i "incomplete" >%systemroot%\temp\delbatch\step2.txt
::Jeden Ordner auf der Liste "step2.txt" löschen
for /f %%a IN (%systemroot%\temp\delbatch\step2.txt) DO rmdir /s /q "%%a"
Sollte eigentlich laufen. Melde dich auf jeden Fall, egal ob es geklappt hat oder nicht.
Edit:
"<Pfad zu deinem Ordner>" musst du natürlich noch mit dem entsprechenden Pfad ersetzen
Eine VBS-Variante mit einem kleinen Schönheitsfehler sähe etwa so aus:
' MoveEmptyFoldersAccordingToPartOfName.vbs
Const BaseFolder = "D:\Test\" ' immer abschließenden "\" verwenden
Const MoveTo = "E:\Temp" ' nie abschließenden "\" verwenden
Const CheckFor = "complete" ' "incomplete" wird, da "complete" enthaltend, damit auch gefunden
L = Len(BaseFolder)
Set fso = CreateObject("Scripting.FilesystemObject")
If fso.FolderExists(BaseFolder) Then
If Not fso.FolderExists(MoveTo) Then
fso.CreateFolder(MoveTo)
End If
DoFolders fso.GetFolder(BaseFolder)
Else
WScript.Echo "Startordner " & BaseFolder & " nicht gefunden!"
WScript.Quit(1)
End If
WScript.Echo "Fertig."
Sub DoFolders(Folder)
For Each SubFolder In Folder.SubFolders
DoFolders SubFolder
' Auf der untersten Verzeichnisebene beginnen, um auch erst durch
' das Script geleerte Verzeichnisse berücksichtigen zu können
If (SubFolder.SubFolders.Count + SubFolder.Files.Count) = 0 Then
If InStr(LCase(SubFolder.Name), CheckFor) = 0 Then
MoveFolder SubFolder.Path
End If
End If
Next
End Sub
Sub MoveFolder(SourcePath)
RelPath = Mid(SourcePath, L + 1) ' Relativer Pfad unterhalb von "BaseFolder"
Tree = Split(RelPath, "\")
TargetPath = MoveTo
' Verzeichnisstruktur unterhalb von "MoveTo" schrittweise erstellen
For i = 0 To UBound(Tree)
TargetPath = TargetPath & "\" & Tree(i)
If Not fso.FolderExists(TargetPath) Then fso.CreateFolder(TargetPath)
Next
fso.DeleteFolder SourcePath
WScript.Echo SourcePath & ";" & TargetPath
End Sub
Begründung dafür: Einerseits muss (im Gegensatz zu einer Batch-Version) in VBS ohnehin der Pfad schrittweise (Unterverzeichnis für Unterverzeichnis) erstellt werden, andererseits scheint (für mich überraschend) ein Verschieben von Verzeichnissen auf eine andere Partition (zumindest unter XP und WSH 5.6) per VBS nicht möglich.
Gedacht ist das Script für eine Verwendung von der Kommandozeile, zB
cscript //nologo "C:\Scripts\MoveEmptyFoldersAccordingToPartOfName.vbs"
Grüße
bastla
willkommen im Forum auch von mir.
Dann will ich auch noch eine CMD-Prompt-Variante beisteuern.
Anders als in bastlas Ansatz möchte ich aber auf die Rekursivität (unbekannte/beliebige Anzahl Verzeichnisebenen) verzichten und von einer festgelegten Anzahl Ebenen ausgehen.
Nicht weil es am CMD-Prompt nicht rekursiv ginge, sondern weil es unnötige Komplexität in dieses banale Problem hineinbrächte.
Wenn wir von einer konstanten Anzahl Unterebenen ausgehen (meinetwegen 3, die uns gleich wieder wieder als %a, %b und %c begegnen) dann sollte es wie im folgenden Beispiel gehen.
Gegeben sei folgende Verzeichnis/Dateistruktur (erst alles, dann nur DIRs, dann nur FILEs):
Z:\>
$cmd$dir Beutelsuppe /b /s
Z:\Beutelsuppe\BS 01
Z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 1
Z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 2
Z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 3
Z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 4
Z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 1\somewhat.tmp
Z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 3\this is complete
Z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 3\this is complete\01.jpg
Z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 4\this is incomplete
Z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 4\anyFile.tmp
Z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 4\this is incomplete\00.sfv
Z:\>
$cmd$dir Beutelsuppe /b /s /a:d
Z:\Beutelsuppe\BS 01
Z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 1
Z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 2
Z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 3
Z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 4
Z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 3\this is complete
Z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 4\this is incomplete
Z:\>
$cmd$dir Beutelsuppe /b /s /a:-d
Z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 1\somewhat.tmp
Z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 3\this is complete\01.jpg
Z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 4\anyFile.tmp
Z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 4\this is incomplete\00.sfv
Denn diese enthalten einen Unterordner mit dem Signalwort "complete".
Ordner "..1" und "...2" könnten/müssten verschoben werden.
Hier kann noch differenziert/verfeinert werden: Ordner "..1" enthält eine Datei, Ordner "...2" ist vollkommen leer.
Tasten wir uns ran mit 3 Ebenen (%a %b %c) am CMD-Prompt:
$cmd$for /d %a in (z:\Beutelsuppe\*) do @for /d %b in ("%a\*") do @for /d %c in ("%b") do @if not exist "%b\*complete*" @echo %c
"z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 1"
"z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 2"
Wenn zusätzlich keine Datei darin sei darf, dann können wir das testen, weil sich beide beim "Dir /s /b" unterschiedlich verhaltnn
[Exkurs]
$cmd$dir "z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 2\" /b /s
$cmd$dir "z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 1\" /b /s
z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 1\somewhat.tmp
Bei Ordner "..2", der weder Dateien enthält noch Unterordner wird nichts gefunden.
Also ändern wir die rechte Tu-Was-Seite der Zeile auf
$cmd$for /d %a in (z:\Beutelsuppe\*) do @for /d %b in ("%a\*") do @for /d %c in ("%b") do @if not exist "%b\*complete*" @dir "%b\*.*" /s/b|find /i "%b">nul || @echo %b
z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 2
Gut, der Rest ist einfach. Der Arbeits-Teil, der bisher aus
...md "y:\sicherheitskopie\%~pnxb" && rd "%b"
-oder-
..md "y:\sicherheitskopie\%~pnxb" && xcopy /s /e "%b\*.*" "y:\sicherheitskopie\%~pnxb" && rd "%b"
So oder so sollte es mit einem Oneliner vom CMD-Prompt gehen, auch für mehrere Startverzeichnisse:
$cmd$for /d %a in (d:\temp\arm\* z:\Beutelsuppe\*) do @for /d %b in ("%a\*") do @for /d %c in ("%b") do @if not exist "%b\*complete*" @echo %c
"d:\temp\arm\Arm 001\Neuer Ordner_Neuer Ordner 1"
"d:\temp\arm\Arm 001\Neuer Ordner_Neuer Ordner 2"
"z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 1"
"z:\Beutelsuppe\BS 01\Neuer Ordner_Neuer Ordner 2"
Grüße
Biber