108. Festplattenspeicherfresser mit Batch finden
Einleitung
Seit zwei Abhandlungen (Tabellenbearbeitung
mit Batch und Doublettenfinder)
beschäftigt sich der Sternenhimmelstuermer nun mit der sinnvollen
Verwendung des For-Befehls. Dieses ist ist dann wieder so eine
Abhandlung, die als Abfallprodukt entstand -:). Der Weg ist das Ziel
und wird hier vorgestellt: Eine Dateiliste mit Dateigröße, Dateinamen
und Dateipfad wird erstellt. Aus der Liste werden die
Dateien ab einer bestimmten Größe, die Sie anpassen sollten,
als Logdateien herausgegeben und eine Zeile mit Dateigröße,
Dateinamen und Dateipfad in einen Ergebnistext ausgegeben.
Hier wird nur wieder nur das voll funktionsfähige Grundmuster in zwei
Batches gegliedert wiedergegeben. Das kann dann nach belieben von
ambitionierten Batchschreibern angepasst werden. Bei Veröffentlichung
natürlich mit einem Verweis auf diese Seite oder Nennung des Namens
Sternenhimmelstuermer. Der Name ist eine einschlägig bekannte Marke...
Die Erklärung nur kurz, aber für Anfänger sind mehrere Highlights
verständlich erklärt worden...
Batches
1. Batch mit beliebigerName.bat
SET /p pfad=geben Sie den pfad zum Ordner an!
set /p Dateiendung=Geben sie die Dateiendung ohne Punkt ein
for /f "delims=" %%i in ('dir %pfad%\*.%Dateiendung% /s /b /a-d') do @echo %%~zi^:%%~ni^:%%i >>gro.log
FOR /F "tokens=1,2,3* delims=:" %%i IN (gro.log) DO echo %%i %%j %%k^:%%l >>%%i.log
FOR /F "tokens=1,2,3* delims=:" %%i IN (gro.log) DO call genial.bat %%i %%j %%k:%%l
del *.log
2. genial.bat (Die
muss so heißen, nicht nur weil Einfachheit genial ist...)
set /a x=%1
if %x% lss 50000 del %x%.log
if %x% GEQ 50000 echo %1 %2 %3 >> ergebnis.txt
end
Erklärung
SET /p pfad=geben Sie den pfad
zum Ordner an!
set /p Dateiendung=Geben sie
die Dateiendung ohne Punkt ein
Mit set /p wird immer
etwas abgefragt und das abgefragte in den variablen pfad und Dateiendung
gespeichert.
Mit chcp 28591 > NULwerden ü,ä und ö escaped.
Das ist sinnvoll, da die dateien sonst unter den Tisch fallen - ein
deutsches Problem. Vor jedem For - Befehl zwingend notwendig, wenn der
Inhalt verschoben wird...
for /f "delims=" %%i in ('dir
%pfad%\*.%Dateiendung% /s /b /a-d') do @echo %%~zi^:%%~ni^:%%i >>gro.log
Viele User können leider keine passenden Tabellen mit Angabe von
Name:Größe: Dateiname erstellen - insbesondere nicht von
Unterverzeichnissen. Genau das macht diese Zeile! Der User gibt den
obersten Ordner an und der Dir-Befehl
arbeitet sich durch die Unterverzeichnisse durch...
Es bietet sich eine Hybridform mit Arbeitsteilung an: dir bis * ist der Pfad (%pfad%) zu beliebigen Dateien
- *.%Dateiendung% : * sind also die Dateien mit .%Dateiendung% . Zur Erinnerung %Dateiendung% ist die
Variable für die Dateiendung, die der User am Anfang eingab: Also z. B.
PDF
Ab /s beginnen die
Parameter des Dir
Befehls : /s -
Unterordner werden durchsucht /b
blanke Dateinamen abgefragt /a-d
schauen Sie bitte in der cmd unter
dir /? Returntaste in der Windowshilfe der CMD nach. Ab do @echo sind wir wieder bei
anteilen der For-Schleife. %%i
ist jeweils die vom dir-Befehl
gefundene Datei mit der Dateiendung PDF in unserem Pseudobeispiel.
Die Abfragetechnik %%~zi
^:%%~ni ^:%%i steht für Dateigröße in Bytes Dateinamen und
kompletter Dateipfad. Mit ^:
werden einfach nur Doppelpunkte als Schriftzeichen generiert, die wir
als Seperatoren für unsere "Tabelle" verwenden. Das ganze wird in einem
Dokument Namens gro.log Zeilenweise ausgegeben.
FOR /F "tokens=1,2,3*
delims=:" %%i IN (gro.log)
DO echo %%i %%j %%k^:%%l >>%%i.log
Jetzt arbeiten wir uns zeilenweise durch die Liste gro.log und erstellen für
jede Zeile eine Log-Datei. Keine Sorge - die sind gerade mal ein KB
groß und es geht relativ fix... Das %%k^:%%l ist so eine
Spezialität des Sternenhimmelstuermers. Im Dateipfad auf dem PC ist ja
immer der Laufwerksname C: - Genau dieser Doppelpunkt ist aber für die
For-Schleife ein Seperator (delims=:).
Gut, andere Batchschreiber würden einfach ein Semikolon benutzen - aber
wozu? Ausgegeben wird jeweils ein Dokument, dass die Dateigröße im
Namen hat: %%i.log. Bei doppelten
größen stehen dann eben zwei Zeilen im Dokument...
FOR /F "tokens=1,2,3*
delims=:" %%i IN (gro.log)
DO call genial.bat %%i %%j %%k:%%l
Jetzt gehen wir nochmal in die Dateiliste mit den ganzen Zeilen
sämtlicher Dateigrößen, Namen und Pfade - ein notwendiger
Zwischenschritt:
Wir rufen nun call
für jede Zeile des Dokuments eine Batch auf, der die Drei Werte einer
Zeile mit dem seperator Doppelpunkt übergibt. Sie kennen das vielleicht
mit Anführungsstrichen in der Art ""%%i" %%j". Glauben Sie dem
Sternenhimmelstuermer: in einer for Schleife geht es auch so. %%k:%%l ist wieder Pfad C:\blabla... Der Doppelpunkt
ist Separator und in der eben genannten Form ist das so in diesem Fall
ohne ^ richtig:
Denn wir verlassen nun einmal kurz die Batch und folgen der Bearbeitung
in die genial.bat für
diese eine Zeile:
set /a x=%1
if %x% lss 50000 del
%x%.log
if %x% GEQ 50000 echo %1 %2 %3 >> ergebnis.txt
end
Wir können uns nun richtig schön mit den Variablen austoben, die an die
Batch übergeben wurden (%%i
%%j %%k:%%l)
Die sind jetzt für die genial.bat als Name 1% 2% und 3% abrufbar - in der
Reiehenfolge- wie Sie übergeben wurden, also %%i entspricht der Dateigröße
und somit in dieser genial.bat
1 % (bei den %1 Variablen findet in der
Batch keine Prozentzeichenverdopplung statt). Für %%j steht 2% und für den Block %%k:%%l stehen 3 %.
Damit wird es jetzt richtig einfach und die kryptischen folgenden
Zeilen werden lächerlich einfach
set /a x=%1
Wir setzen die Dateigrößenzahl (ehemals
%%i in dem For-Befehl ) als Variablenzahl (/a macht das
zur Zahlenvariable) x.
if %x% lss 50000
del %x%.log
Mit dem If -Befehl
vergleichen wir nun zwei Zeichenfolgen. Der Sternenhimmelstuermer
setzte die Zahl zum Vergleich willkürlich auf 50000 Bytes. Sie können
die Dateigröße sinnig umändern, um Dateien über 1 GB zu finden: Die
Eingabe muss in Bytes erfolgen: Googlen Sie mal, was 1 GB in Bytes
ist...
lss ist einer der Vergleichsparameter, die Sie in der Hilfe der cmd
unter if /? abfragen
können. Lss heißt
Zeichenfolge kleiner als: Also heißt der Befehl übersetzt: Wenn der X-
( ehemals %%i oder
Bytewert aus der Dateiliste...)Wert kleiner als 50000 Bytes ist, dann
lösche del die Datei mit
dem Namen des X-Wertes.log.
Den W-Wert-Log erstellten wir aus der Dateiliste in der ersten Batch
mit der Zeile : FOR
/F "tokens=1,2,3* delims=:" %%i IN (gro.log) DO echo %%i %%j
%%k^:%%l >>%%i.log
- Nur mal so zur Erinnerung.
if %x% GEQ 50000 echo %1 %2 %3 >> ergebnis.txt
Das ist nun der Fall, wenn (if)der
X-Wert gleich oder größer (GEQ)
50000 ist, dann werden (echo)
%1 (ehemals %%i oder Dateigröße) %2 (Dateiname mit Endung oder
ehemals %%k) und %3 (der Dateipfad) in
einem Textdokument namens ergebnis.txt ausgegebn (>> ergebnis.txt).
Danach hat der Mohr seine Schuldigkeit getan, er kann nun gehen oder
bzw. wird die Datei einfach (end)
beendet.
Das Prozedere erfolgt nun für jede Zeile aus gro.log, da der For Befehl (FOR /F "tokens=1,2,3*
delims=:" %%i IN (gro.log)
DO call genial.bat %%i %%j %%k:%%l) stur
alle Zeilen abarbeitet und unsere kleine genial.bat je nach Listengröße
sich einige Male bis tausende Male öffnet und immer dieselbe Funtion
durchläuft.
Sobald der For Befehl beendet ist, geht es im letzten Schritt in der
ersten Batch weiter: Die reatlichen Log-Dateien werden der Ordnung
halber zerstört del
*.log und übrig bleibt der Ergebnistext.
Fazit
Diese Abhandlung bringt auf einfache Weise viele Erklärungen für u. a.
Verwendung der 1 %-Variable,
Anwendung von For-Befehlen. Der Sternenhimmelstuermer umschiffte einige
Schwierigkeiten mit setlocal... und schuf in Bezug auf Seperatoren auch
bewußt kleine Fallen im For-Befehl.
Schwierige Befehle wurden bewußt ignoriert - zum Ungunsten der
Performance, aber irgendwie ging es ja nur um die Bearbeitung von
Tabellen und dem For-Befehl zum Auslesen. Das Ganze in einer sinnvollen
Form ausgeben - und dieses Ziel wurde in dieser kleinen Abhandlung
erreicht.
Klar, man könnte auch Dateigrößenwerte abfragen und diese übergeben und
kann sich hunderte von Variationen vorstellen - allein durch die
genial.bat, die Sie dank des flexiblen Quellcodes auch als Anfänger
leicht erweitern können.
Damit endet erstmal diese For -Reihe, weil der Sternenhimmelstuermer
diesen Befehl zur Zeit nicht mehr sehen kann...