Mit folgenden Accesskeys steuern Sie auf dieser Seite:
Ziffer 0 zurück zum Seitenanfang. Ziffer 1 zur Hauptnavigation. Ziffer 2 zur Metanavigation. Ziffer 3 zum Inhalt.
Mit folgenden Accesskeys steuern Sie auf meiner Homepage:
Buchstabe A zur Startseite. Buchstabe K Kontakt.
In der Quicksearch-Box rechts können Sie den Namen eines Windows-Kommandos oder
Kommandozeilentools eingeben
und kommen so schnell zu dessen Beschreibung.
Hit Hilfe der Ausgabeumlenkung ">" kann man die Ausgabe, die auf der
Konsole erscheint, z.B. in eine Datei umleiten. Eine vorhandene Datei
wird bei einem einfachen ">" überschrieben. Bei Verwendung eines
doppelten ">>" wird die Ausgabe an die angegebene Datei
angehängt.
Es gibt zudem ein spezielles Gerät namens "nul" (es entspricht dem /dev/null
unter UNIX), das als Müllschlucker dient. Alles was man hierher sendet,
wird nicht in einer Datei angelegt, sondern ins Nirvana geschickt.
Beispiel:
Das Kommando "pause" liefert eine Standardmeldung, die zum Drücken einer
Taste auffordert. Dieser Text ist bei einer engl. Windows-Version ebenfalls
englisch (ist ja klar).
Um diese Ausgabe durch eine eigene Meldung zu ersetzen, die dem Benutzer
z.B. vielleicht einen genaueren Status anzeigt, zeigt man den gewünschten
Text mit echo an. Die Ausgabe des Kommandos pause wird umgeleitet:
echo weiter mit beliebiger Taste oder [Strg]+[C] zum abbrechen.
pause >nul
Mit Hilfe der einfachen Ausgabeumleitung mit Hilfe des >-Zeichens
hinter einem Kommando, wird die produzierte Ausgabe des aufgerufenen
Kommandos unterdrückt. Tritt ein Fehler auf, sieht man die Fehlermeldung
trotzdem am Bildschirm. Ursache ist, dass es neben dem "Standardausgabekanal"
auch einen "Fehlerkanal" gibt. Um Fehlermeldungen ebenfalls zu unterdrücken,
gibt man vor dem Umleitungszeichen eine 2 (die Nummer des umzuleitenden Kanals)
an:
Beispiel:
mkdir %temp%\workdir 2>nul
... erzeugt das Verzeichnis "workdir" im TEMP-Ordner. Sofern es bereits existieren
sollte, erscheint die Fehlermeldung "Verzeichnis existiert bereits" nicht.
Schlüssel zum Erfolg ist das Kommando "exist" - meist ist es mit einer
if-Klausel anzutrefen:
if exist [Dateiname] [auszuführendes Kommando, wenn Datei existiert]
Beispiel:
Anbei eine Bat-Datei, die prüft, ob der erste übergebene Parameter eine
existierende Datei ist:
@echo off
if exist %1 goto TUWAS
echo ERROR: Datei "%1" nicht gefunden!
goto ENDE
:TUWAS
echo Jepp - die Datei "%1" existiert... - ich zeige sie mal an:
type "%1"
:ENDE
Wiederum kann man dies mit "exist" prüfen. Genaugenommen prüft exist
das Vorhandensein von einer Datei oder aber einem Verzeichnis.
Um abzusichern, dass es sich um ein Verzeichnis und eben nicht
um eine Datei handelt, kann man auf das Gerät nul zurückgreifen.
Dieses befindet sich scheinbar in jedem Verzeichnis:
if exist [Verzeichnis]/nul [auszuführendes Kommando, wenn Datei existiert]
Beispiel:
Anbei eine Bat-Datei, die prüft, ob der erste übergebene Parameter ein
existierendes Verzeichnis ist:
@echo off
if exist %1/nul goto TUWAS
echo ERROR: Verzeichnis "%1" nicht gefunden!
goto ENDE
:TUWAS
echo Jepp - das Verzeichnis "%1" existiert... - ich liste es auf:
dir "%1"
:ENDE
Bat-Beispiel
Eine andere Möglichkeit wäre der Aufruf des dir-Kommandos,
wo man mit Hilfe des Parameters /a die gewünschten File-Attribute angibt.
Manchmal möchte man eine fehlgeschlagene Aktion in der
BAT-Datei wiederholen.
Das Problem dürfte sein: Wie zähle ich die Anzahl der Versuche?
Eine typorientierte integer Variable, die man hochzählen kann, gibt es bei
BAT-Dateien nicht...
Man kann sich aber mit Stringvergleichen behelfen. Man definiert
eine Variable für den Counter und eine weitere für die Anzahl Maximum
der Versuche. Bei jedem Durchlauf wird der Counter um ein
(bestimmtes) Zeichen erweitert. Es wird beendet, wenn der Counter
meinem Maximum entspricht.
Anbei eine Demo-BAT-Datei, die das verdeutlichen soll:
@echo off
rem --- Variablen setzen ---
set counter=
set maxcount=xxxxx
rem --- MAIN ---
:RUNHERE
echo --- Ich tu hier was...
:: Hier muesste eine Aktion und eine Verzweigung
:: fuer den erfolgreichen Durchlauf hinein...
:: if %ERRORLEVEL%==0 goto ENDE
set counter=%counter%x
if "%counter%"=="%maxcount%" goto ERRMAX
echo %counter%
echo ich warte kurz ...
ping -n 5 localhost >nul
goto RUNHERE
:ERRMAX
echo SORRY - max. Anzahl der Versuche wurde erreicht.
goto ENDE
rem --- EXIT ---
:ENDE
pause
Bat-Beispiel
Bei neueren Windows-Versionen kann man mit Zahlenwerten rechnen
und einen Counter erhöhen - die "Krücke" mit dem String braucht
man nicht. Man verwende einfach
set /a [Variable]=[Zuweisung]
set counter=0
set maxcount=5
(...)
set /a counter=%counter% + 1
if "%counter%" EQU "%maxcount%" goto ERRMAX
(...)
Die schlechte Nachricht vorweg: direkt auf die Registry kann
man (natürlich) nicht zugreifen. Aber man kann sich behelfen.
Unser Helfer heisst diesmal regedit. Dieses ist nicht nur
ein Programm, sondern es sind 2 Programme in einer EXE-Datei
(ein sog. DOS-Stub und Windows-Stub). Wenn der Befehl regedit
ohne Parameter unter Windows aufgerufen wird, bekommen Sie die
grafische Oberfläche des sicher bekannten Registry-Editors zu
sehen. Befinden Sie sich im DOS-Modus oder aber setzen Sie einen
Parameter dahinter, startet das Konsolenprogramm.
Um aus der Registry zu lesen, muss man den gewünschten gewünschten
Schlüssel zunächst exportieren:
regedit /e [Dateiname] [Registry-Schlüssel]
In der erzeugten Textdatei kann man die Textsuche nach den
gewünschten Informationen ansetzen.
Hier ein Beispiel, um die Werte eines Schlüssels anzuzeigen:
@echo off
set REGFILE=%TEMP%\~regpart.reg
set REGFOLDER=HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
regedit /e %REGFILE% %REGFOLDER% >nul
echo [%REGFOLDER%]:
type %REGFILE% | find "="
del %REGFILE%
Bat-Beispiel
Anmerkungen:
Es werden mit regedit /e automatisch immer alle Unterschlüssel
exportiert. Das obige Beispiel funktioniert nur deshalb
(zufällig) korrekt, weil der gewählte Schlüssel keine
Unterschlüssel besitzt.
Unter Windows XP gibt es das Kommandozeilen-Tool REG, mit
dem sich Zugriffe auf die Registry einfacher gestalten.
Mit Hilfe von regedit kann man via Batchfile auch
die Registry verändern. Möglich sind:
Anlegen von Schlüsseln und Werten
Ändern von Werten
Löschen von Schlüsseln und Werten
Voraussetzung zur Manipulation der Registry ist eine ASCII-Datei,
die die "Anweisungen" zum Ändern/ Löschen enthält: eben eine
REG-Datei. Deren Syntax mit Angabe von Schlüsseln und Werten
können Sie sich ansehen, indem Sie einen Export der Registry
ausführen.
s.a.
aus der Registry lesen
Um eine REG-Datei zu importieren, ist regedit mit deren
Dateinamen aufzurufen. Der Import der Registry-Datei erfolgt
ohne eine Rückfrage, indem man zusätzlich den Parameter
/s (für silent) verwendet:
Einen "echten Debugger" gibt es nicht. Mit folgenden Praktiken
kann man sich aber etwas behelfen:
Zeilenweises Ausführen von BAT-Dateien
Das kann man lediglich mit kleinen Skripten machen.
COMMAND /Y /C [Befehl]
bzw. unter NT4, Win2000/ ME:
CMD /Y /C [Befehl]
gezieltes Setzen von @echo on und echo off.
Mit @echo on werden die auszuführenden Kommandos
in die Standardausgabe gescrieben. Es entspricht
in etwa den Optionen set -vx und set +vx in der
UNIX-Shell.
echo on
echo Ab hier werden die ausgefuehrten Kommandos wiederholt
echo %temp%
(...)
@echo off
echo Ab hier wird nur die Ausgabe der Kommandos angezeigt.
echo %temp%
Einbau von Variablenausgaben und Pausen
Stoppen Sie die Abarbeitung des Skriptes durch den
Einbau des Kommando "pause" - lassen Sie zuvor die
gewünschten Variablen ausgeben.
Wenn in einem Firmennetzwerk alle User dieselben Shares mit
bestimmten LW-Buchstaben verbunden haben sollen, sollte man
diese am besten im Logon-Skript verarbeiten. Falls bereits ein
Laufwerk verbunden sein sollte, trennt man zunächst die
bestehenden Mappings.
@echo off
echo Trenne Laufwerke...
for %%a in (h i j k) do echo N | net use %%a: /del
echo.
echo Verbinde Laufwerke...
net use H: \\SERVER_1\SHARE_1 >nul
net use I: \\SERVER_1\SHARE_2 >nul
net use J: \\SERVER_2\SHARE_1 >nul
net use K: \\SERVER_3\SHARE_1 >nul
Um ein zweites Ausführen des Skriptes zu testen, muss man auf das
letzte Ausführungsdatum zurückgreifen können. Das geht z.B., indem
man sich das Ausführungsdatum bei Erfolg in einer Textdatei sichert.
Nachfolgendes Beispiel funktioniert mit der deutschen Version von Window98
(für andere Sprachen müssen die fett hervorgehobenen Texte angepasst werden):
@echo off
:: -- Variablen
set datefile=letzte_ausführung.txt
set tmpfile=aktueller_zeitstempel.tmp
:: -- aktuelles Datum in eine Datei schreiben
echo. | date | find /i "aktuelles" > %tmpfile%
:: ... und mit letztem Zeitstempel vergleichen
fc %tmpfile% %datefile% | find "FC: Keine Unterschiede festgestellt" >nul
if errorlevel 1 goto machwas
echo INFO: Skript wurde heute schon einmal ausgefuehrt.
goto ende
:machwas
echo.
echo INFO: Hier kommen die eigentlichen Aktionen des Skripts hin
:: -- aktuelles Datum als letzte Ausfuehrung vermerken.
move %tmpfile% %datefile%
goto ende
:ende
Bat-Beispiel
Anmerkung zu anderen Windows-Versionen:
Zum Ermitteln des aktuellen Datums wird hier für Win95/ 98
echo. | date | find /i "aktuelles" > %tmpfile%
verwendet. Unter Win NT/2K kann einfacher
date /t > %tmpfile%
geschrieben werden.
Das Errorlevel
fc %tmpfile% %datefile% | find "FC: Keine Unterschiede festgestellt" >nul if errorlevel 1 goto machwas
ist ebenfalls typisch Windows 95/98; unter NT kann man es wiederum sprachenunabhängig schreiben:
fc %tmpfile% %datefile% >nul if %ERRORLEVEL%==1 goto machwas
Hinweis
Um die Ausführung alle n Tage zu gestatten: Run_if_older
Die schlechte Nachricht vorweg: Man kann mit Bordmitteln und
Beachtung der Abwärtskompatibilität nur ganze Zeilen
austauschen. Falls wer Unix-Shellskript kennt, dem empfehle ich die
Installation von CYGWIN - dann lässt sich z.B. die Bash nutzen und
auch weitere Tools wie der Streameditor, awk oder tr (was man in den
meisten Fällen besser gebrauchen könnte).
Mit Windows XP gibt es ebenfalls noch ein paar weitergehende
Möglichkeiten.
was immer geht:
Das nachfolgende Beispiel wäre eine Anwendung für ganzzeiliges
Ersetzen in Dateien: in der hosts-Datei wird der Eintrag für den
(fiktiven) Rechner "testserver.example.com" ausgetauscht. Nachteile hierbei
sind:
es werden keine Passagen, sondern eine komplette Zeile ersetzt
der neue Eintrag wird zuunterst in der Datei eingefügt und
nicht bei der aktuellen Stelle
set hostsfile=%windir%\system32\drivers\etc\hosts
set tmpfile=%temp%\hosts.tmp
rem -- vorhandenen Eintrag entfernen und in Temp-Datei schreiben
type %hostsfile% | find /v "testserver.example.com" >%tmpfile%
rem -- neuen Eintrag der Temp-Datei hinzufügen
echo "123.123.456.456 testserver.example.com">>%tmpfile%
rem -- Temp-Datei in Hostfile umbenennen
move %tmpfile% %hostsfile%
Bat-Beispiel
ab Windows XP
Man kann
Im set-Befehl kann man Zeichenketten ersetzen (dazu folgt gleich ein Beispiel)
set A=%PATH:str1=str2%
... und Zeichen im String abschneiden, z.B. ab dem 11. Zeichen 5 Zeichen ausgeben:
%PATH:~10,5%
... oder einfach den Platzhalter % für Variablen verwenden
In der Hilfe von For sind diverse Ersetzungen zur Zerlegung
von Pfad, Dateinamen, Extension, Zeitstempel und Grösse
genannt
auch hilfreich: das Entfernen des doppelten Hochkommas.
So brauche ich oftmals das Verzeichnis des aktuellen Skripts,
wenn ich im selben Verzeichnis eine Konfiguration lesen
oder eine weitere Datei aufrufen will.
unschöne Variante:
set cfgfile=0%\..\inc_config.bat
besser:
set scriptdir=%~dp0%
set cfgfile=%scriptdir%\inc_config.bat
Am besten, du schaust mal in die Hilfe-Ausgabe von
Im aktuellen Verzeichnis werden die Dateinamen ermittelt (dir /b *.*).
Wenn ein Umlaut auftaucht (s. Zeile set chars= ...),
wird der unerwünschte Buchstabe angezeigt. Dann wird das Label :replace angesprochen.
Darin wird ausgegeben, wie ein Dateiname ohne Umlaut aussehen kann. Hierzu
werden mehrere Ersetzungen hintereinander durchgeführt.
Und noch ein wichtiger Hinweis: Die Umlaute/ Sonderzeichen im nachfolgenden
Quelltext sind im ASCII-Modus zu schreiben- die Umlaute nicht in notepad & Co.
einfügen, sondern z.B. mit edit in der Eingabeaufforderung).
@echo off
set chars=ä ö ü è é
echo.
echo ===== schlechte Dateinamen ======
echo.
for /F %%a in ('dir /b *.*') do (
for %%m in (%chars%) do (
echo %%a | find /i "%%m">nul && echo schlecht: [%%m] in %%a
)
call :replace "%%a"
)
echo.
echo Suche beendet. Taste druecken zum Beenden.
pause>nul
exit
:replace
set newname=%1
set newname=%newname:ä=ae%
set newname=%newname:ö=oe%
set newname=%newname:ü=ue%
set newname=%newname:è=e%
set newname=%newname:é=e%
if NOT "%newname%"=="%1" echo ----- Vorschlag zum Umbenennen: && echo VON : %1 && echo NACH: %newname% && echo.
Dateien mit Umlauten ausfindig machen
Beispiel 2:
Nehmen wir mal folgendes Template an:
::
:: Die 2 Doppelpunkte am Zeilenanfang sind Kommentarzeichen.
:: Durch Anpassung des findstr kann man aber auch andere Zeilen ausfiltern.
::
Test-Template zum Ersetzen eines Textes
Name: %sName%
Vorname: %sVorname%
Betreff: %sBetreff%
template.txt
... darin ersetze ich die Variablen mit %-Platzhalter (wie in der Batch-
Schreibweise) mit vorgegebenen Umgebungsvariablen.
Zunächst setze ich die Variablen mit einem normalen SET. Das Template
wird einmal ungefiltert ausgegeben (mit TYPE).
Dann wird die Textdatei gelesen (wobei Template-Kommentare mal ausgefiltert
werden) und deren Textinhalt ersetzt.
Der Trick besteht darin, die Textzeile nicht direkt bei der for-Schleife,
sondern erst im Label :replace das echo auszuführen.
Die Zeile
set line=%line:Ersetzen=Manipulieren%
ersetzt wie im obigen Beispiel einen vorgegebenen statischen Text.
@echo off
set template=template.txt
set sName=Mustermann
set sVorname=Klaus
set sBetreff=Dies ist eine vordefinierte Betreffzeile.
echo --- das Template:
type %template%
echo.
echo --- ersetzen der Platzhalter und eines einfachen Textes:
for /F "tokens=*" %%a in ('type %template% ^| findstr /v "^::"') do call :replace "%%a"
echo.
echo --- fertig.
goto end
:replace
set line=%~1
set line=%line:Ersetzen=Manipulieren%
echo %line%
goto end2
:end
pause & exit
:end2
Ersetzen von Zeichen und Variablen mit %
... und das ist die Ausgabe:
--- das Template:
::
:: Die 2 Doppelpunkte am Zeilenanfang sind Kommentarzeichen.
:: Durch Anpassung des findstr kann man aber auch andere Zeilen ausfiltern.
::
Test-Template zum Ersetzen eines Textes
Name: %sName%
Vorname: %sVorname%
Betreff: %sBetreff%
--- ersetzen der Platzhalter und eines einfachen Textes:
Test-Template zum Manipulieren eines Textes
Name: Mustermann
Vorname: Klaus
Betreff: Dies ist eine vordefinierte Betreffzeile.
--- fertig.
Drücken Sie eine beliebige Taste . . .
net send: an mehrere Benutzer dieselbe Nachricht senden
Mit dem Kommando net send kann man an einen Benutzer (bzw. Rechnernamen)
eine Nachricht senden. Auch eine bestimmte Nachricht an die ganze Domain
abzsetzen, ist mit einem einzelnen Aufruf möglich. Möchte man
an ausgewählte Benutzer/ Rechner eine Botschaft senden, sind mehrere
Aufrufe von net send erforderlich.
@echo off
:: Liste der Empfaenger:
set userlist=jana susi mary anna
:: Hier die Nachricht eintragen:
set sMsgText=Es gibt nun Kaffee und Kuchen fuer alle ... Euer Axel
echo on
for %%a in (%userlist%) do net send %%a %sMsgText%
@echo off
echo %0 beendet.
pause
Manchmal braucht es zwischen 2 Aktionen in einer Batchdatei eine kleine
Pause. Ein Kommando wie sleep gehört nicht zum Befehlsumfang, aber man kann
sich mit dem ping-Kommando behelfen:
Der Parameter /n [Anzahl] pingt einen angegebenen Rechner entspr. der
mitgegebenen Anzahl an. Dabei liegt zwischen den Pings ca. 1 Sekunde. Da
der erste Ping sofort ausgelöst wird, kann man, um x Sekunden zu warten,
die Anzahl (x+1) angeben.
Und was pingt man nun an? Am besten das, was immer da sein sollte: localhost.
Last but not least: Damit die ganze Ausgabe des Ping-Kommandos nicht sieht,
leitet man selbige in das Nul-Device um.
@echo off
echo.
echo Anzeige der momentanen IP-Adresse:
echo.
ipconfig | find /i "ip-adresse"
echo.
echo ich schliesse in 5 Sekunden....
ping /n 6 localhost >nul
Benutzereingaben lassen sich in neueren Windowsversionen mit
set /p Variablenname=[angezeigter Text]
realisieren.
Folgendes Beispiel fragt nach einer Benutzereingabe, sofern dem Skript kein
Parameter mitgegeben wird. Der Benutzer bekommt einen blinkenden Cursor
vorgesetzt und muss seine Eingabe, die im Klartext angezeigt wird, mit
[Return] abschliessen. Der Wert wird in der Variable testvar gespeichert.
@echo off
if "%1"=="" goto eingabe
set testvar=%1
goto ausgabe
:eingabe
set /p testvar=Irgendetwas eingeben:
goto ausgabe
:ausgabe
echo Ausgabe zur Kontrolle:
echo testvar=%testvar%
pause
Bat-Beispiel
Anmerkung zu anderen Windows-Versionen:
Ich glaube, der Parameter /p beim Kommando SET existiert
erst ab Windows 2000 (oder auch NT4) - auf jeden Fall funktioniert
dieses Beispiel nicht mit Windows 95/98 oder DOS.
Befehle:
set
Diese Eingabezeile ist zudem recht "schlicht". Wer mehr
Comfort bieten möchte, kann sich WBAT auf Horst Schaeffers Batch Pages
ansehen - hiermit lassen sich recht einfach ganze GUIs bauen: neben
Eingabezeilen sind auch Radiobuttons, Checkboxen, Listenelemente
und so einiges mehr möglich. Wie das so alles funktioniert, schaut
man sich aus dem mitgeliefertem Demo ab.
Ein Ansatz für eine mehrsprachige Ausgabe wäre die Verwendung einer
Textsuche. Mit Labels kann man eine Art Prozedur abhandeln wie in
höheren Programmiersprachen: man kann auch Parameter übergeben -
der erste ist als %1 abrufbar.
Die Suche in der Sprachendatei erfolgt nach einer Zeichenkette
(Keyword + Sprachkuerzel), die sich am Zeilenanfang befinden soll:
findstr "^%1_%lang%" %langfile%
Zum Abschneiden des Prefix in der Ausgabe wird alles von einer For-Schleife
umgeben und mit Hilfe der Tokens entfernt:
FOR /F "delims=_ tokens=3-6 " %%a IN ('findstr "^%1_%lang%" %langfile%') do echo%%a %%b %%c %%d
Wer die For-Anweisung jetzt nicht versteht, bekommt umfangreiche Erklärungen
samt Beispiel mit dieser Eingabe im Kommandozeilenfenster:
for /?
Jetzt muss ich nur noch wissen, wie ich meine Texte anzeigen lasse:
call :DisplayInfo welcome
wobei :DisplayInfo mein angesprungenes Label in derselben Bat-Datei ist,
und "welcome" mein Kürzel für den anzuzeigenden Text.
Nachteile
... dir mir bekannt sind:
Performance ... naja, wenn es darauf ankäme, schreibt man ja auch keine Batchfiles.
Variablen in den Texten werden nicht expandiert
In den Texten darf der Trenner zw. Keyword und Textzeile nicht verwendet werden.
Das Trennzeichen wird immer herausgeschnitten
Nachfolgendes Beispiel können Sie kopieren, als BAT-Datei speichern und
einmal damit experimentieren.
Hier sind die Texte in der Bat-Datei selbst untergebracht - man muss dafür
sorgen, dass die Sprachtexte niemals durch die Ausführung der Datei erreicht
werden können - sonst hagelt es Syntax-Fehler:
@echo off
set lang=de
:: set lang=en
set langfile=%0
rem ----------------------------------------------------------------------
:: eigentliches Skript - Aufruf der Texte "welcome" und "pause"
rem ----------------------------------------------------------------------
call :DisplayInfo welcome
call :DisplayInfo pause
pause >nul
goto end
rem ----------------------------------------------------------------------
:: Modul zur Ausgabe der sprachabhaengigen Texte
rem ----------------------------------------------------------------------
:DisplayInfo
FOR /F "delims=_ tokens=3-6 " %%a IN ('findstr "^%1_%lang%" %langfile%') do echo%%a %%b %%c %%d
goto end
rem ----------------------------------------------------------------------
:: sprachabhaengige Texte
rem ----------------------------------------------------------------------
welcome_de_.
welcome_de_ Informationen
welcome_de_.
welcome_de_ Zeile2 ... mit etwas Text ...
welcome_de_ Zeile3
welcome_de_ Zeile4
pause_de_ Druecken Sie [Strg]+[C] zum abbrechen ... weiter mit beliebiger anderer Taste
welcome_en_.
welcome_en_ informations
welcome_en_.
welcome_en_ ...
pause_en_ Press [Strg]+[C] to cancel ... or any key to continue
rem ----------------------------------------------------------------------
:: ENDE
rem ----------------------------------------------------------------------
:end
Um einen kompletten Dateinamen - bestehend aus Laufwerk, Pfad und Dateinamen -
in seine Bestandteile zu zerlegen, gibt es mit dem FOR einige Ersetzungsmöglichkeiten.
Mit Hilfe der Ersetzungen kann man z.B. den Pfad, den Dateinamen und die Extension
erhalten.
for /?
Hilfe für FOR aufrufen
Bei sonstigen Zeichenketten kann man mit den Optionen delims=[Trennzeichen] und tokens=[Nr.]
arbeiten, um eine Zeichenkette zerlegen.
In nachfolgendem Beispiel wird der Pfad der win.com im Windows-Verzeichnis zerlegt:
@echo off
set sFullname=%windir%\win.com
for %%i in ("%sFullname%") do set sPATH=%%~di%%~pi
for %%i in ("%sFullname%") do set sFILE=%%~ni%%~xi
for /F "delims=. tokens=1" %%i in ("%sFILE%") do set sPart1=%%i
for /F "delims=. tokens=2" %%i in ("%sFILE%") do set sPart2=%%i
echo sFullname=%sFullname%
echo sPATH=%sPATH%
echo sFILE=%sFILE%
echo sPart1=%sPart1%
echo sPart2=%sPart2%
pause
Ausgabe eines Befehls in eine Variable holen (Win2k)
Zunächst muss man wissen, in welchem Format die Ausgabe eines Kommandos daherkommt
und wie man die gesamte Ausgabe nach der gewünschten Zeile filtern kann.
Oft steht die gewünschte Information dann auch nicht allein in der Zeile -
dann muss man noch die anderen Informationen ausblenden.
Am einfachsten ist dies mit der FOR-Schleife zu bewerkstelligen. Mit den Parametern
TOKENS und DELIMS lässt sich die Ausgabe effektiv beschneiden.
Das Setzen der Variable erfolgt mit dem normalen SET Befehl.
rem -- Beispiel 1 --
For /F "tokens=2 Delims=:" %%i in ('ipconfig /all^|Find /i "DNS"') Do @Set DNSSERVER=%%i
echo DNSSERVER=%DNSSERVER%
rem -- Beispiel 2 --
For /F "tokens=3" %%i in ('Net Config Workstation^|Find /i "Arbeitsstationsdom„ne"') Do @Set WORKGROUP=%%i
echo WORKGROUP=%WORKGROUP%
rem -- Beispiel 3 --
set sTMPFILE=%temp%\~test.tmp
regedit /e %sTMPFILE% "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion"
For /F "tokens=2 Delims==" %%a in ('type %sTMPFILE%^| find "ProductId"') do @set winSerial=%%a 2>nul
del %sTMPFILE%
echo Windows-Serial Number=%winSerial%
Ausgabe eines Befehls in eine Variable packen (Windows 2000)
so holt man den Wert aus der Registry in eine Variable - das funktioniert mit Hilfe der
reg.exe, die XP beiliegt:
Hinweise:
Der erste Befehl könnte mehrere DNS-Server zurückgeben (wg. alternativen DNS-Servern
als auch bei mehreren Netzwerkkarten) - beachte, dass per Default in der For-Schleife
nur der letzte Wert zurückgeliefert wird. Mehr zu dieser Eigenheit erfährst
du nach Eingabe "for /?" in der Kommandozeile.
Das Auffinden der Workgroup oder Domäne sucht nach einem deutschen String. Bei einem anderssprachigen Betriebssystem funktioniert dieser Aufruf schon nicht mehr.
regedit exportiert immer alle untergeordneten Schlüssel. Unter XP sollte man reg einsetzen:
Dies ist wesentlich schneller und einfacher zuschreiben (aber eben nicht kompatibel zu älteren Win-Versionen).
Dieser Aufruf ermittelt den Ordner der History des IE (alles ist in eine Zeile zu schreiben):
For /F "tokens=3* delims=[tab_druecken]" %%i in
('reg QUERY "HKEY_CURRENT_USER&Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" /v "History" ^| findstr /i "History"')
Do set HistoryDir=%%i
Ausgabe von reg in eine Variable packen (Windows XP)
Die Zeichen < und > haben in einer Batchdatei Ein- und Ausgabefunktionen.
Der ganze "Trick" für eine HTML-Ausgabe besteht darin, diese Zeichen zu maskieren,
damit man sie in die Ausgabe schreiben kann:
rem -- Ausgabedatei
set htmlout=%temp%\logfile.html
rem -- HTML generieren
echo ^<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"^> >>%htmlout%
echo ^<HTML^>^<HEAD^> >>%htmlout%
echo ^<TITLE^>HTML-Ausgabe-Test^</TITLE^> >>%htmlout%
echo ^</HEAD^>^<BODY^> >>%htmlout%
echo ^<H1^>HTML-Test^</H1^> >>%htmlout%
date /t >>%htmlout%
time /t >>%htmlout%
echo ^<HR /^> >>%htmlout%
echo Hello world.^<HR /^> >>%htmlout%
echo ^</BODY^>^</HTML^> >>%htmlout%
rem -- Browser starten
start %htmlout%
Oft ist es gut, wenn man Informationen aus einer Textdatei liest,
statt in einer Batchdatei diese als Variablen abzulegen oder
zigfach dieselbe Kommandofolge zu wiederholen. Anpassungen
erfolgen dann in einer Konfigurationsdatei und derjenige,
der die Anpassung macht, braucht nicht im Skript herumfuhrwerken.
Um eine Textdatei zu parsen, brauchen wir eine Textdatei,
aus der wir die Informationen auslesen wollen. Neben den
auslesbaren Nutzdaten sollte man Kommentare verwenden
können.
Zu Demo verwende ich einmal die folgenden Konventionen:
Kommentare sind Zeilen, die mit # beginnen
Trennzeichen in meiner Konfiguration ist das Pipe-Symbol: |
... und so kann es aussehen:
# ==================================================
# DEMO-Konfiguration
# Syntax:
# Kuerzel | Anzeigename | zu startendes Programm
# ==================================================
E|Explorer|explorer.exe
W|MS Write|write.exe
P|MS Paint|paint.exe
# -- ENDE
Konfigurationsdatei
Wenn man ein Menü darsellen möchte, braucht man jeweils das
erste und zweite Feld aus fer Konfigurationsdatei.
Das Parsen erfolgt mit Hilfe des findstr-Befehls. Die Kommentare
kann man mit dem Parameter /v rauswerfen. Dies zeigt alle
Zeilen exklusive die mit # am Zeilenanfang:
type menu.txt | findstr /v "^#"
Desweiteren müssen wir wissen, wie wir die überbleibenden
Informationen anhand unseres Trenner-Symbols auseinandernehmen
können. Dies geht mit Hilfe des For-Kommandos.
Mit dem Parameter /F geben wir an, dass eine Kommandoausgabe geparst werden
soll. Mit der Angabe delim wird das Trennzeichen angegeben.
Innerhalb der Schleife kann man mit der angegebenen Variable
auf den ersten Wert zugreifen; mit dem nächstfolgenden
Buchstaben auf den zweiten Wert usw.:
echo Programmauswahl:
for /F "tokens=1,2 delims=|" %%a in ('type menu.txt ^| findstr /v "^#"') do (
echo Taste %%a ... %%b
)
Um eine Datei zufällig auswählen zu können, braucht man:
man muss die Anzahl der Dateien als Wert in eine Variable holen
einen Zufallswert zw. 1 und der Anzahl der Dateien ermitteln
aus dem Zufallswert wieder die Datei zurordnen.
Ich lasse so z.B. den Windows-Startsound zufällig bestimmen.
In der Systemsteuerung ist eine fixe Datei beim Windows-Start
festgelegt. Das Batchscript wählt zufällig eine Wav-Datei
aus einem Verzeichnis und überschreibt die eingestellte
Sound-Datei. Zuguterletzt ist das Batchfile im Autostart-Ordner.
In den nachfolgenden Codeschnipeln hole ich mir in Variablen:
anzahlWav - Anzahl der WAV-Dateien
i - Zufallswert
myfile - meine zufällige Datei, die an Stelle i steht
Anzahl Dateien holen
In eine Variable anzahlWav hole ich die Anzahl Dateien:
:: get count of files
set targetfile=random.wav
set anzahlWav=0
for /F "tokens=1 delims=:" %%b in ('dir /b %mydir%\*.wav ^| findstr /v "%targetfile%" ^| findstr /n "." ') do set anzahlWav=%%b
Anzahl der Dateien ermitteln
Erläuterungen:
Ich brauche zunächst eine Liste der Dateien. Dazu hilft mir das Kommando
dir /b [Filter]
In dieser Ausgabe lasse ich nach einem beliebigen Zeichen suchen und missbrauche
findstr /n ".", um eine Nummerierung der Zeilen einzufügen.
Mit einem findstr /v "%targetfile%" verhindert man, dass die Zieldatei nicht mitgezählt wird.
Zufallswert
In eine Variable i sole ich meinen Zufallswert:
set /a i=%random%*%anzahlWav%/32767+1
Zufallswert holen
Erläuterungen:
In der Variable %random% steckt ein Zufallswert zw. 0 und 32767.
Man muss erst mit der Anzahl multiplizieren und dann durch diesen Wert
dividieren, da ganzzahlig gerechnet wird.
Datei Nr. i holen
In eine Variable sourcefile hole ich die Datei an der Stelle i wieder:
set myfile=
for /F "tokens=2 delims=:" %%b in ('dir /b *.wav ^| findstr /v "%targetfile%" ^| findstr /n "." ^| findstr "^%i%:"') do set myfile=%%b
Dateinamen holen
Die Vorgehensweise ist nahezu analog dem Zählen der Datei. Nun suche ich aber
in der Ausgabe noch nach meiner Nummer i, die am Zeilenanfang steht und der
ein ":" folgt.