infobase: EDV - DOS
Batch-Dateien
FOR-Schleife, lange und kurze Dateinamen
Quelle: dmt
Datum: 03.2009
Lange und kurze Dateinamen, Pfadnamen und die doofe FOR-Schleife in Batch-Files:
Das mit den langen Pfad- und Dateinamen hat in Microsoft-Systemen schon IMMER Ärger gemacht.
Das ich ausgerechnet dazu und zum Thema Batch-Dateien und FOR-Schleifen noch was im Jahre 2006 nachzutragen habe, ist irgendwie abartig.
Mein Problem:
Ein sehr flotter und erkennungsstarker Virenscanner (F-Prot), der in der DOS-Version seinen Dienst ohne jegliche Installation verrichtet (ich liebe so was), kam mit den leider in der Windowswelt vorkommenden langen Datei- und Pfadnamen nicht zurecht.
Da der Aufruf meiner Virenscanner-Sammlung per Kontextmenü für Dateien und Ordner erfolgt und das Ganze erfolgreich über eine DOS-Batchdatei abgewickelt wird, war ich gezwungen, mit DOS-Bordmitteln zu erreichen, daß eine lange Pfad- und Dateiangabe in eine reguläre, kurze umgewandelt werden kann.
Der Weg:
Eine Webrecherche wies auf Möglichkeiten hin, die in Batchdateien mittels FOR-Schleifen realisiert werden können. Bewaffnet mit einigen Beispielen und der umfangreichen Befehlsdokumentation ('help for') machte ich mich an's Werk:
Der Rest bestand in einer mehrstündigen Rumtester- und Ausprobiererei.
Die sprachliche Implementierung diverser Optionen für die Batch-FOR-Schleife ist aus meiner Sicht eines Hochsprachen-Programmierers mehr als beschissen. Da sich aber in der Doku der Hinweis auf eine Lösung fand, wollte ich partout nicht locker lassen:
Ein Auszug:
Zusätzlich wurde die Ersetzung von Verweisen auf FOR-Variablen erweitert.
Diese Parameter können auch miteinander kombiniert werden:
%~fsi - expandiert %i zu einem vollständigen Namen, der nur kurze Dateinamen enthält
Ja, ich war begeistert.
Nach einigen Stunden schrumpfte die Begeisterung, aber die Ausdauer hat sich gelohnt.
Und weil ich absolut keinen Bock habe, wegen dieses Drecks noch einmal Zeit zu investieren, schreibe ich mir den Mist auf:
Ein Wort vorneweg zu dem, was in Programmiersprachen als Syntax bezeichnet wird:
- Wenn ich eine Variable deklariere, schreibe ich einfach ihren Namen (
SET variable=88
).
- Wenn ich sie verwende, muß sie von Prozentzeichen umschlossen sein (
echo %variable%
)
- Ein Parameter, der als Variable von außen kommt, braucht ein führendes Prozentzeichen (
echo %1
)
- Eine Variable innerhalb einer FOR-Schleife benötigt aber ZWEI führende Prozentzeichen (
%%i
)
Ihr habt sie doch nicht mehr alle, ihr Deppen von der Kleinweich-Front !
Wie in diesem Syntax-Scheißhaufen der Hinweis auf %~fsi - expandiert %i zu einem vollständigen Namen, der nur kurze Dateinamen enthält
korrekt implementiert werden soll, blieb mir erst mal ziemlich schleierhaft.
Nach irre langer Probiererei führte endlose Geduld dann doch zum Ziel:
Die Zeile
FOR /D %%i IN (%1) DO (SET ShortFileOrDirName=%%~fsi)
bewirkt, daß %1 (enthält langen Pfad und Namen einer Datei bzw. eines Verzeichnisses) in einen regulären, kurzen Pfad- und Dateinamen umgewandelt wird und als Wert in der Variablen ShortFileOrDirName landet.
Erläuterung:
FOR
eröffnet das unheimliche DOS-Batch-Schleifen-Spiel
/D
setzt die Schleifenabarbeitung in einen Modus, der was mit Dateien und Verzeichnissen zu tun hat
%%i
steht für eine Variable i, die innerhalb der Schleife diverse Werte annehmen kann
IN (%1)
bezeichnet eine Art Menge, die abgearbeitet wird (hier nur die eine %1-Angabe), die Schleife wird also nur einmal durchlaufen
- Nach
DO
kommt das, was pro Schleifendurchgang zu tun ist
SET ShortFileOrDirName=%%~fsi
weist der Variablen ShortFileOrDirName die kurze Pfad/Dateinamen-Version dessen zu, was sich in %1 befindet
Eine Anwendung, die als Parameter nur gekürzte Pfad- und Dateinamen akzeptiert, kann dann in der Batchdatei wie folgt aufgerufen werden: f-prot.exe %ShortFileOrDirName%
Weitere Beispiele:
FOR /D %%i IN (c:\windows\*.*) DO (echo %%~fsi)
gibt die Namen aller Unterverzeichnisse unter c:\windows in gekürzter Form aus.
FOR /R %%i IN (*) DO (echo %%~fsi)
listet alle Dateien in allen Unterverzeichnissen unterhalb des aktuellen und gibt deren Namen in der Kurzform aus..
Was Lustiges:
Wenn ich z.B. den aktuellen Laufwerksbuchstaben oder das aktuelle Arbeitsverzeichnis in Variablen sichern möchte (falls die Batchdatei wilde Wechsel vornimmt), kann das auch mittels FOR-Schleifen geschehen:
FOR /D %%i IN (drecksau) DO (echo %%~di)
erzeugt einen einmaligen Schleifen-Durchgang und gibt die Laufwerksbezeichnug aus. Das mit dem drecksau
ist keineswegs ein schlechter Scherz, denn ohne Angabe in der Klammer würde gar nichts ausgegeben und mit z.B. einem *
erfolgt die Ausgabe so oft, wie Unterverzeichnisse gefunden werden. Eine beliebige Deppenangabe läßt die Schleife genau einmal durchlaufen.
Genauso geht es mit dem aktuellen Arbeitsverzeichnis: FOR /D %%i IN (drecksau) DO (echo %%~pi)
Mit Blick auf den Virenscanner F-Prot wollte ich obendrein den reinen, kurzen Dateinamen extrahieren und dazu feststellen, ob per Windows-Parameter ein Dateiname oder ein Verzeichnis übergeben wurde:
rem **** Kurze Darstellung des Dateinamens von %FullShortFileOrDirName ****
FOR /D %%i IN (%FullShortFileOrDirName%) DO (SET ShortFileOrDirName=%%~nxi)
rem **** Ist der kurze Name ein Verzeichnis ? ****
IF NOT EXIST %ShortFileOrDirName% SET ShortFileOrDirName=*.*
Konfiguration
diverse
Datum: alt
SWITCHES/F: bootet 2 s schneller (ab DOS 6).
FILES:
Windows setzt FILES mind. als 40 gegeben. Bei Files > 40 setzt Windows die Angabe erneut um 10 hoch.
SMARTDRIVE:
Empfehlung smartdrv 1536 768 /E:8192 /B:32.
smartdrv /s sollte Trefferquotient von mind. 7:1 zeigen. Besser 12:1.
smartdrv A+ B+ 2048 1024 /E:8192 /B:32 aktiviert Scheibcache für Disk.
BUFFERS:
Mit Smartdrv sind 8 genug. Ohne bei 120 MB-Platte mind. 40.
RAMDRIVE:
Ausschließlich für Windows: Ramdisk im konventionellen Speicher.
Max. ca 450 kB. evtl. Programme draufkopieren.
FASTOPEN:
Kann auch zus. zu Smartdrv mit hohen Werten was bringen: c:=200.
MSCDEX.EXE
/S erlaubt mehreren Benutzern CD-Sharing im Netz.
Speichermanagement
emm386.exe
Datum: 03.2004
freie Grafikkarten-Bereiche
VGA i=B000-B7FF
EGA i=B800-BFFF
Herkules i=A000-AFFF
CGA i=A000-B7FF i=BC00-BFFF
Standardmäßig sucht EMM386 in C000-DFFF freie Bereiche. Ohne EMS kann -
außer bei IBM PS/2 - i=E000-EFFF gesetzt werden. Oft können zus. 32 kB durch i=F000-F7FF freigesetzt werden. (Vorsicht: BIOS-Bereich, meist nur BIOS-Setup zum Booten -> wenn das gut geht, kann i=D000-EF7FF gesetzt werden.) Wenn BIOS älter als 12.12.1991, sind in F000-F7FF auch Systemroutinen abgelegt. Das ROM einer VGA-Karte liegt in C800-C7FF. Der Rest des C-Segments kann mit i=C800-CFFF benutzt werden, wenn nicht andere Steckkarten diesen Bereich benötigen.
Maximal würde gelten: i=C800-F7FF.
Für den Bildschirmspeicher ist A000-BFFF reserviert. Unter VGA gilt max. i=B000-B7FF i=C800-F7FF.
Bei Abstürzen F-Segment raus: i=C800-EFFF: Das bringt 192 kB und läuft auf allen Rechnern außer PS/2 !
Falls Windows nicht mehr mitspielt, kann mit monoumb.386 aus \dos nach \windows\system kopiert, in [386Enh] mit device=monoumb.386 eingetragen, experimentiert werden. ( Frank Kraus, ex. Bit&Byte )
Bei reiner Textdarstellung geht i=A000-B7FF.
Fehlt speziell für Windows XMS: noems win=B000-B7FF win=C800-EFFF.
Installhigh
Datum: alt
Treiber grundsätzlich mit INSTALL(HIGH) schon in CONFIG.SYS laden.
NOVELL-Treiber IPXNE20.COM und NETX.COM nur mit LH in AUTOEXEC.BAT.
Wenn das nicht geht, ermöglicht EMSNETX.COM das Hochladen.