Vor dem Problem, grössere Mengen an Dateien umzubenenen, steht man hin und wieder,
zumindest, wenn man sich mit Musik oder digitaler Photografie beschäftigt,
jpegs und mp3s sammlen sich gerne in unbezwingbaren Mengen.
Nun gibt es ja auch Tools, die so etwas erledigen können, selbst der Explorer in WinXP
hat eine einfache Funktion zum Umbenennen mehrerer Dateien eingebaut.
Diese Aufgabe lässt sich jedoch auch gut von einem Script erledigen,
und das werde ich hier Schritt für Schritt schreiben:
(Grundkenntnisse werden angenommen)
Egal was man macht, ein Plan ist nie verkehrt, also:
1) Plan machen
a) Was soll das Script tun?
Alle Dateien in dem aktuellen Verzeichnis umbenennen. Und zwar indem der Name
des Verzeichnisses vor den Dateinamen gestellt wird, so dass man sie später
in einem gemeinsamen Verzeichnis immer noch auseinander halten kann.
Verzeichnisname|Trennzeichen|Dateiname.Dateiendung
b) Angenommen, das Script funktioniert, also macht genau das, was es soll.
Das Script befindet sich (meist) selbst in dem Verzeichnis, also würde es sich
auch selbst umbenennen. Warum? Weil es ja genau das macht, was es soll.
Das wäre in dem Fall aber nicht so gut!
c) Also neuer Plan:
Das Script soll alle Dateien in dem Verzeichnis mit Ausnahme von sich selbst umbenennen.
Woher weis das Script, wie sein Name ist?
Man könnte sich darauf verlassen, dass das Script immer gleich heisst und den Namen
fest im Code angeben. Das wäre aber nicht gut gelöst. Besser ist die Variable %0
zu verwenden, die immer auf das Script selbst zeigt. Gebraucht wird aber nur
der Dateiname (n-Name) und die Endung (x-eXt), also heisst es: %~nx0
if not "%dateiname%"=="%~nx0" ren "%dateiname%" "Verzeichnisname%datename%"
d) Das Verzeichnis:
Dazu muss man wissen, dass es mehrere Arten gibt, das Verzeichnis zu ermitteln. Die
bekannteste ist wohl der cd Befehl. Einfach mal in eine Eingabeaufforderung eingeben.
Mit dem Befehl kann man von einem ins andere Verzeichnis wechseln, sich aber auch
das aktuelle Verzeichnis anzeigen lassen. Parallel zu dem Befehl gibt es bei cd
eine Variable cd, deren Inhalt wie bei jeder Variable durch Prozentzeichen
ermittelt werden kann. In der Eingabeaufforderung: echo.%cd%
2) In der Praxis kommt es doch anders
(also macht man eine test.cmd)
@echo off echo. echo.Die Variable cd dieses Scripts: echo. echo %cd% echo. echo.Zum Beenden: pause
(und startet sie der Doppelklick)
Die Variable cd dieses Scripts:
C:\Dokumente und Einstellungen\User\Eigene Dateien
Zum Beenden:
Drücken Sie eine beliebige Taste . . .
Die Ausgabe ist jedesmal der aktuelle Pfad, in dem auch das Verzeichnis enthalten ist.
Eigentlich genau das was gebraucht wird, man muss nur irgendwie das Verzeichnis
da heraus trennen (natürlich nur den Namen). Mit Win2000 wurde die
Batchscript-Sprache von Windows für diese Zwecke erweitert.
Anmerkung: Um das aktuelle verzeichnis zu ermitteln gibt es bestimmt fertigen Code,
auf den hier aber verzichtet wurde. Es ist nämlich ein gute Aufgabe um einige
weniger bekannte Funktionen der cmd anzuwenden, die sehr sinnvoll sind.
3) Ein paar Hintergründe
In der Programmierung nennt man das, was jetzt benötigt wird, Stringmanipulation. Welche Zeichenfolge
manipuliert werden soll, ist klar, nämlich C:\Dokumente und Einstellungen\User\Eigene Dateien
Mit den Erweiterungen der cmd wurde auch Syntax zur Stringmanipulation eingeführt, er ist
ein wenig kryptisch. Im Grossen und ganzen lassen sich die Methoden so erklären:
Alles ab eine gewissen Position von vorne, bis zu einer gewissen Position von da aus gesehen.
Was sich erstmal trivial anhört sieht dann so aus:
(Beispiel mit dem systempath,
für die Eingabeaufforderung)
echo.%path%
echo.%path:~2,5%
Es lässt sich erraten, von dem, was in path steht, wird alles ab dem 2. Zeichen von vorne,
bis zu den nächsten 5 Zeichen (also bis zum 7. Zeichen absolut betrachtet) ausgegeben.
Und wenn man das Ende abschneiden will?
Alles von vorne (ab Position 0 also) bis zur..... Ja, bis wohin eigentlich? Wie lang ist denn
der String überhaupt? Das braucht man zum Glück nicht wissen, denn es gibt noch eine Möglichkeit,
die zweite Position, also bis wohin in der Zeichenkette, anzugeben.
Dazu wurde das Minuszeichen definiert:
echo.%path%
echo.%path:~2,-5%
Alles ab eine gewissen Position von vorne, bis zu einer gewissen Position vom Ende aus gesehen.
3) Der spezielle Fall:
Es bietet sich eine besondere Möglichkeit der Stringmanipulation an, die von der cmd angeboten wird:
Alles bis zum ersten Antreffen eines gewisen Zeichens wird gestrichen, inklusive dem Zeichen selbst.
Wenn man jetzt aber mal schaut:
gegeben ist: C:\Dokumente und Einstellungen\User\Eigene Dateien
gesucht ist: Eigene Dateien
Wäre es natürlich sinnvoll, alles bis zum letzten Antreffen eines Zeichen zu streichen, nämlich
alles bis zum Antreffen des letzten \ und nicht bis zum ersten \. Dazu ist mir aber kein Sytax bekannt.
Also muss man sich mit etwas behelfen, man trennt einfach solange alles bis zum ersten \ ab, bis man
beim letzten \ angekommen ist. Da eine Pfadangabe nicht unendlich lang sein kann, geht das sehr schnell.
Ein weiteres Beispiel für die Eingabaufforderung:
echo.%path%
echo.%path:*sys=%
Die Ausgabe fängt logischerweise mit tem32 (vom ersten windows\system32 im path) an. Für das Script
wäre %name:*\=% die Variante, die alles bis zum ersten \ streichen würde. Dieser Schritt muss solange
wiederholt werden, bis sich nichts mehr ändert, weil es kein \ mehr gibt:
C:\Dokumente und Einstellungen\User\Eigene Dateien
Dokumente und Einstellungen\User\Eigene Dateien
User\Eigene Dateien
Eigene Dateien
5) Das Script entsteht langsam:
@echo off echo. color f0 title FileRename set filename=%cd% :cutname set testname=%filename% set filename=%filename:*\=% if not "%filename%"=="%testname%" goto :cutname echo.%filename% echo. pause
Das Script muss ertsmal ausführlich getestet werden, bevor es an das Umbenennen geht. Dazu wird es
einfach aus den unterschiedlichsten Verzeichnissen heraus gestartet, mit kurzen Namen, mit langen
Namen, mit Leerzeichen, ohne Leerzeichen, aus dem Wurzelverzeichnis, usw.
Dabei zeigt sich, dass es überall funtioniert, nur im Wurzelverzeichnis, also z.B. in C:\ ist es noch
ein wenig buggy. Nicht verwunderlich, gibt es doch hier überhaupt keinen Verzeichnisnamen.
echo."%cd:*\=%" gibt im Wunzelverzeichnis "" aus. So etwas lässt sich recht einfach abfangen:
if "%cd:*\=%"=="" set /p filename=Name to add:
Wenn "%cd:*\=%" das gleiche wie "" ist, wird mit dem set-Befehl, genauer gesagt,
durch set /p eine Benutzereingabe mit der Anzeige "Name to add:" gefordert.
6) Der Code wächst:
@echo off echo. color f0 set filename=%cd% :cutname set testname=%filename% set filename=%filename:*\=% if not "%filename%"=="%testname%" goto :cutname if "%cd:*\=%"=="" set /p filename=Name to add: && echo. echo.%filename% echo. pause
Damit verfügt das Script jetzt immer über einen sinnvollen Text, den es zum Umbenennen
verwenden kann. Entweder wird der Name des Verzeichnisses genommen, in dem sich das Script
befindet oder, falls es im Wurzelverzeichnis sein sollte, kann der Benutzer den Text
eingeben. Man könnte jetzt noch testen, ob der Benutzer auch wirklich einen sinnvollen
Text eingegeben hat. In diesem Fall dürften keine verbotenen Sonderzeichen dabei sein,
weil Dateien so benannt werden sollen. Aber so etwas kann immer noch dazugefügt werden,
erstmal ist es wichtiger, das das Script funktioniert.
Es sollen alle Dateien umbenannt werden. Weil dabei jeweils der exakte Name der Datei gebraucht wird,
müssen alle Dateien einmal durchgegangen werden. Dafür gibt es den for-Befehl,
der einen anderen Befehl auf jedes Element einer Aufzählung anwendet.
Die Aufzählung sind hier alle Dateien im Verzeichnis (*):
Beispiel für die Eingabeaufforderung:
for %i in (*) do @echo %i
Gibt eine Liste aller Dateien im jeweilgen Verzeichnis aus. Das funktioniert so nicht in einer
Batch. Der Syntax für die Eingabaufforderung und Scripte unterscheiden sich bei dem for-Befehl.
Beispiel für ein cmd-Script:
@echo off
for %%i in (*) do echo %%i
7) Das fertige Script:
@echo off echo. color f0 title FileRename set delimiter=- set filename=%cd% :cutname set testname=%filename% set filename=%filename:*\=% if not "%filename%"=="%testname%" goto :cutname if "%cd:*\=%"=="" set /p filename=Name to add: && echo. echo.List of new filenames: echo. for %%i in (*) do if not "%%i"=="%~nx0" echo.%filename%%delimiter%%%~i echo. echo. echo.Press any key to rename pause >nul for %%i in (*) do if not "%%i"=="%~nx0" ren "%%~i" "%filename%%delimiter%%%~i" echo. echo.Press any key to end pause >nul goto :eof
Das ist das fertige Script. Obwohl es tadellos funktioniert, sollte man immer einen Blick auf
die Liste mit den neu gebildeten Dateinamen werfen, bevor man durch Tasendruck den Vorgang
zum Umbenennen auslöst. Sollten die neuen Dateinamen aus welchen Gründen auch immer nicht
den Erwartungen entsprechen, kann man das Fenster mit dem Script einfach per Maus
schliessen, natürlich ohne dass irgendwelche Dateien umbenannt wurden.
Eine Beispielausgabe des Scripts, im Verzeichnis
C:\Dokumente und Einstellungen\User\Eigene Dateien\Bilder01
List of new filenames:
Bilder01-bugzilla.png
Bilder01-calendar.png
Bilder01-camino.png
Bilder01-debian button-1.gif
Bilder01-debian button-2.gif
Bilder01-debian button-3.jpg
Bilder01-debian openlogo-nd-100.jpg
Bilder01-debian openlogo-nd-100.png
Bilder01-eclipse21.JPG
Bilder01-firefox blank.gif
Bilder01-firefox rediscover.png
Bilder01-google.gif
Bilder01-google_alien.gif
Press any key to rename
Press any key to end <-----(erscheint natürlich erst nach dem Umbenennen)
8) Ein kleines Bild dazu:
Das Script nach erledigter Arbeit:
Erhebt keinen Anspruch auf Perfektion.
greetz,
2cool
-------------------------------------------------------------------------------
C:\>help
Geben Sie HELP 'Befehlsname' ein, um weitere Informationen
zu einem bestimmten Befehl anzugeigen.
Dieser Beitrag wurde von 2cool bearbeitet: 27. Mai 2006 - 10:09