WinFuture-Forum.de: Wie man ein CMD-Script schreibt - WinFuture-Forum.de

Zum Inhalt wechseln

Nachrichten zum Thema: Entwicklung
Seite 1 von 1

Wie man ein CMD-Script schreibt an example


#1 Mitglied ist offline   2cool 

geschrieben 27. Mai 2006 - 09:50

Wie ein Script ensteht:

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:

Eingefügtes Bild






Erhebt keinen Anspruch auf Perfektion. :D

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

greetz, 2cool

web: cmd-script
mail: [email protected]
0

Anzeige



#2 Mitglied ist offline   Graumagier 

  • Gruppe: aktive Mitglieder
  • Beiträge: 8.811
  • Beigetreten: 01. März 04
  • Reputation: 1
  • Geschlecht:Männlich
  • Wohnort:Graz, Österreich

geschrieben 27. Mai 2006 - 09:59

Ohne jetzt sofort meckern zu wollen, aber würde das nicht besser ins How-To-Forum passen? Frag mal einen Mod ob er das verschiebt.

Ansonsten ein gutes Tutorial :D
"If you make something idiot proof, someone will invent a better idiot." - Marvin

For Emails always use OpenPGP. My KeyID: 0xA1E011A4
0

#3 Mitglied ist offline   stefanra 

  • Gruppe: aktive Mitglieder
  • Beiträge: 6.208
  • Beigetreten: 13. September 04
  • Reputation: 1

geschrieben 27. Mai 2006 - 10:27

Klasse, endlich ein Howto zu diesem Thema! :D

Es würde anundfürsich schon gut ins Howto-Forum passen, aber da in letzter Zeit ständig Fragen nach irgendwelchen CMD-Skripten kommen, würde ich dieses Howto jetzt erstmal hier gepinnt lassen.

Wenn die zugehörigen Mods anderer Meinung sind, können sie es ja jederzeit verschieben.
0

#4 Mitglied ist offline   Hauner 

  • Gruppe: aktive Mitglieder
  • Beiträge: 2.297
  • Beigetreten: 03. Januar 05
  • Reputation: 0
  • Geschlecht:Männlich

geschrieben 27. Mai 2006 - 14:08

Zitat

Wenn die zugehörigen Mods anderer Meinung sind, können sie es ja jederzeit verschieben.
Nein, absolut nicht. Ein Leser, der Hilfe bei der Erstellung eines CMD-Scripts braucht, sucht meiner Meinung nach doch erst im Skript/Web-Programmierung-Forum danach, oder? :blink:
0

#5 _Breaker_

  • Gruppe: Gäste

geschrieben 27. Mai 2006 - 14:27

@stefan:
Du könntest es aber mal in dieser Liste verlinken, dann ist es wenigstens vom HowTo aus zugänglich :blink:
0

#6 Mitglied ist offline   Hauner 

  • Gruppe: aktive Mitglieder
  • Beiträge: 2.297
  • Beigetreten: 03. Januar 05
  • Reputation: 0
  • Geschlecht:Männlich

geschrieben 28. Mai 2006 - 12:38

Done. :blink:
Bei der Gelegenheit habe ich auch gleich mal den Titel dieses Threads korrigiert.
0

#7 Mitglied ist offline   Rika 

  • Gruppe: aktive Mitglieder
  • Beiträge: 11.533
  • Beigetreten: 11. Juni 03
  • Reputation: 2
  • Geschlecht:Männlich

geschrieben 28. Mai 2006 - 20:35

Zitat

Dazu ist mir aber kein Sytax bekannt.

Wo ist das Problem? Einfach mit ".." eine Stufe höher gehen, den Pfad expandieren und dann ein Replace. Das Replace kann leider unsauber werden, deshalb muss man die Variable mit etwas anderem als '%' expandieren - nämlich '!'. Dazu natürlich Delayed Expansion anschalten.

set y=%x%\..
for /f "delims=" %%i in ("%x%") do set z=%%~i
set last=%x:!z!=%

Natürlich scheitert dieses Script, wie deines auch, an Dateien, die ein '%', '!', '&' oder '^' im Namen haben. Hier muss man mittels Replace escapen.

set repl=%x:^^=^^^^%
set repl=%repl:^&=^^^&%
set repl=%repl:^!=^^^!%
set repl=%repl:^%=^^^%%


Ansonsten vor allem Quellen zum Syntax mit Variablen:
help for
help if
help set
help cmd
Konnichiwa. Manga wo shitte masu ka? Iie? Gomenne, sonoyouna koto ga tabitabi arimasu. Mangaka ojousan nihongo doujinshi desu wa 'Clamp X', 'Ayashi no Ceres', 'Card Captor Sakura', 'Tsubasa', 'Chobits', 'Sakura Taisen', 'Inuyasha' wo 'Ah! Megamisama'. Hai, mangaka gozaimashita desu ni yuujin yori.
Eingefügtes Bild
Ja, mata ne!

(For sending email please use OpenPGP encryption and signing. KeyID: 0xA0E28D18)
0

#8 Mitglied ist offline   2cool 

geschrieben 28. Mai 2006 - 21:56

.

Beitrag anzeigenZitat (Rika: 28.05.2006, 21:35)

Wo ist das Problem?


Es gibt doch gar kein Problem:


Zitat

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.




Übrigens wollte ich für dieses Beispiel bestimt nicht auf die verzögerte Auflösung von Variablen während der Abarbeitung einer Befehlszeile eingehen. Aber da Du ja davon angefangen hast, wirst Du Dir jetzt bestimmt nicht nehmen lassen, ein nettes kleines HowTo über die Verwedung der Delayed Expansion verfassen.

Natürlich mit getestetem funktionierenden, Code. :)



Gruss,
2cool


btw help zu Befehlen: http://www.free-webs...mdreferenz.html


ist nicht gerade effektüberladen, (Untertreibung) aber darauf kommt es ja auch nicht an.
.
greetz, 2cool

web: cmd-script
mail: [email protected]
0

#9 Mitglied ist offline   Rika 

  • Gruppe: aktive Mitglieder
  • Beiträge: 11.533
  • Beigetreten: 11. Juni 03
  • Reputation: 2
  • Geschlecht:Männlich

geschrieben 28. Mai 2006 - 22:06

Was soll man dazu noch schreiben? Ist doch bei "help if" erläutert :)

BTW, aus der verlinkten Seite:

help > help.txt
for /f "eol= " %i in (help.txt) do echo %i >> commands.txt
del help.txt

Autsch. Wie wär's mit
for /f "eol= " %i in ('help') do echo %i >> commands.txt

?
Konnichiwa. Manga wo shitte masu ka? Iie? Gomenne, sonoyouna koto ga tabitabi arimasu. Mangaka ojousan nihongo doujinshi desu wa 'Clamp X', 'Ayashi no Ceres', 'Card Captor Sakura', 'Tsubasa', 'Chobits', 'Sakura Taisen', 'Inuyasha' wo 'Ah! Megamisama'. Hai, mangaka gozaimashita desu ni yuujin yori.
Eingefügtes Bild
Ja, mata ne!

(For sending email please use OpenPGP encryption and signing. KeyID: 0xA0E28D18)
0

#10 Mitglied ist offline   2cool 

geschrieben 28. Mai 2006 - 22:20

.

Beitrag anzeigenZitat (Rika: 28.05.2006, 23:06)

Was soll man dazu noch schreiben? Ist doch bei "help if" erläutert



Ach komm, keine Ausreden. Das kann man doch besser erklären, als die Microsoft-Hilfe :)



Beitrag anzeigenZitat (Rika: 28.05.2006, 23:06)

Autsch. Wie wär's mit
for /f "eol= " %i in ('help') do echo %i >> commands.txt

?


Wieso "Autsch"?

Macht doch keinen Unterschied. "Autsch" ist für mich etwas anderes.....
.
greetz, 2cool

web: cmd-script
mail: [email protected]
0

Thema verteilen:


Seite 1 von 1

1 Besucher lesen dieses Thema
Mitglieder: 0, Gäste: 1, unsichtbare Mitglieder: 0