mkdeluxe
Goto Top

Hilfe bei Batchdatei

Hallo zusammen,

ich arbeite gerade (zum ersten Mal) mit einer Batch Datei, und brauche kurz Eure Hilfe beim Verständnis. Was macht folgender Abschnitt?

SET FILENAME=Test
IF EXIST "D:\DATEN\Test" (
dir "D:\DATEN\%FILENAME%" > "D:\DATEN\temp.dat"
for /F "tokens=1,2,3 delims=: " %%i in ('findstr Test temp.dat') do call :SUB %%i %%j %%k )

So weit ich das bisher verstanden habe, wird ein Filename deklariert (=Test), und wenn diese Datei existiert (im Verzeichnis D:\...)
dann wird in dem Verzeichnis die Datei mit neuem Dateinamen (temp.dat) reingeschrieben.
Aber, was macht der Rest (for tokens... delims... %%i in...? Am Ende wird dann eine SUB aufgerufen, und wofür stehen dabei %%i %%j %%k?)

So, dann kommt noch in der SUB etwas, dass ich auch nicht verstehe...

:SUB
SET DSTUNDE=%2
SET DMINUTE=%3
SET JAHR=%date:~-2%
SET MONAT=%date:~3,2%
SET TAG=%date:~0,2%
rem SET STUNDE=%time:~0,2%
rem SET MINUTE=%time:~3,2%
SET NEWFILENAME=%MONAT%%TAG%%DSTUNDE%%DMINUTE%.%JAHR%
ren "D:\DATEN\Test" "%NEWFILENAME%"
del "D:\DATEN\temp.dat"

Schon klar, hier wird der Dateiname verändert. Sprich, Dateistunde,-Minute,Jahr, etc. ausgelesen? und später (SET NEWFILENAME, ren...) eingesetzt. Und der temporäre Dateiname temp.dat wird gelöscht. Was ich nicht verstehe: Was passiert durch die Zahlen, also z.B.
SET STUNDE=%2 ?

Und was könnte der Sinn für den Zwischenschritt mit der temp.dat sein?

Danke im Voraus für Eure Hilfe!

Grüße, mkdeluxe

Content-Key: 21942

Url: https://administrator.de/contentid/21942

Printed on: April 19, 2024 at 14:04 o'clock

Member: edv-guru
Solution edv-guru Dec 19, 2005, updated at Feb 19, 2015 at 16:01:01 (UTC)
Goto Top
Hallo,
Soweit ich das kapiere,wird im 1.Teil die Variable Filename=Test gesetzt.Dann wird überprüft, ob eine Datei Existiert, in der der Verzeichnisinhalt(in dem Fall das vorkommen der Datei von Variable FILENAME) von D:\Daten\ steht,wenn nicht wird sie angelegt.
Dann wird sie ausgelesen, wobei mit der for Schleife(siehe cmd --> "help for"oder auch"for /?")die Datei in einer gewissen Länge eingelesen wird.
Im 2.Teil werden verschiedene Variablen mit SET deklariert, wobei(meines Wissens nach) %2 usw. Parameter an die B.Datei sind. dann passiert was undefinierbares ( *ggg*) und dann wird die Datei mit REN umbenannt und die Alte Datei gelöscht.

Gruß
EDV-guru

P.S.: Für weitere Erklärungen warte auf Biber.
Member: mkdeluxe
mkdeluxe Dec 19, 2005 at 14:15:36 (UTC)
Goto Top
Hm...

erst mal danke für die Erklärung. Aber so ganz scheine ich das noch nicht verstanden zu haben... Ich habe mal versucht die beiden Teile halt testweise zusammen zu stellen:

@echo off

SET OLDFILENAME=%TEST%
IF EXIST "Y:\TEST" (
dir "Y:\%OLDFILENAME%" > "Y:\temp.dat "
for /F "tokens=1,2,3 delims=: " %%i in ('findstr TEST temp.dat') do call :SUB %%i %%j %%k )

:SUB
SET DSTUNDE=%2
SET DMINUTE=%3
SET JAHR=%date:~-2%
SET MONAT=%date:~3,2%
SET TAG=%date:~0,2%
rem SET STUNDE=%time:~0,2%
rem SET MINUTE=%time:~3,2%
SET FILENAME=%MONAT%%TAG%%DSTUNDE%%DMINUTE%.%JAHR%
Pause
REN "D:\TEST" "%FILENAME%"

So genau weiß ich zwar nicht was ich da für Stunden und Minuten eingebe, aber das ist erst mal unwichtig. Viel verwirrender ist folgendes: Bis zur Pause läuft das Programm problemlos, aber hinter der Pause bekomme ich die Fehlermeldung: "Das System konnte die angegebene Datei nicht finden." Und zwar egal, ob ich die Datei jetzt im Ordner habe oder nicht. Der Fehler liegt also wohl in meinem REN Befehl, aber wo?
Mitglied: 17243
Solution 17243 Dec 19, 2005, updated at Feb 19, 2015 at 16:01:11 (UTC)
Goto Top
Hi

Bei mir funktioniert der Batch soweit ohne Probleme.
Was mich stört - und wohl auch das OS - dann du bei der letzten Zeile d:\test stehen hast....vorher war es noch y:\test.

Korrigiere mal den Pfad...dann geht der Batch auch.

gretz drop
Member: Biber
Solution Biber Dec 19, 2005, updated at Feb 19, 2015 at 16:01:16 (UTC)
Goto Top
Moin mkdeluxe,

Ivo hat so weit recht... mit der Korrektur könnte es laufen.
Aber Du wolltest ja auch wissen, was in diesem Schnipsel abgeht. Ich versuchs mal ein Stück weit aufzudröseln. Das meiste hast Du ja schon selbst verstanden.

(ich nehme mal den oberen Batch
schnipsel Hauptteil------
SET FILENAME=Test
IF EXIST "D:\DATEN\Test" (
dir "D:\DATEN\%FILENAME%" > "D:\DATEN\temp.dat"
for /F "tokens=1,2,3 delims=: " %%i in ('findstr Test temp.dat') do call :SUB %%i %%j %%k )
schnipsel Hauptteil------

In den ersten drei Zeilen macht der Verfasser seinen eigentlichen Hauptfehler: Er definiert sich eine Variable namens FILENAME mit dem Inhalt "Test"... und fragt aber schon in der nächsten Zeile wieder mit einem hart codierten 'IF EXIST "D:\Daten\Test" '... die Existenz dieser angeblich variablen Datei ab. Geht natürlich in die Grütze, wenn Du statt "SET Filename=Test" irgendwann "Set FileName=*.log" schreibst - das Programm macht immer noch alles davon abhängig, ob eine Datei "Test" existiert...

Also, den kleinen Bug noch weggebügelt, sieht der Hauptteil dann so aus:
schnipsel2 Hauptteil------
SET "FILENAME=Test"
IF EXIST "D:\DATEN\%FileName%" (
dir "D:\DATEN\%FILENAME%" > "D:\DATEN\temp.dat"
for /F "tokens=1,2,3 delims=: " %%i in ('findstr Test temp.dat') do call :SUB %%i %%j %%k )
schnipsel2 Hauptteil------

..ich das bisher verstanden habe, wird ein Filename deklariert (=Test)
Jepp.
und wenn diese Datei existiert (im Verzeichnis D:\...)
Jepp.
dann wird in dem Verzeichnis die Datei mit neuem Dateinamen (temp.dat) reingeschrieben.
Nada.
In der (Teil-)Zeile [dir "D:\DATEN\%FILENAME%" ] wird nicht die Datei "test" irgendwohin geschrieben, sondern nur die Dateiinformationen von "test". Ausgeführt wird ein simples
dir D:\Daten\test
...welches folgenden Output schreiben könnte:
dir d:\Daten\test
Datenträger in Laufwerk D: ist Daten
Volumeseriennummer: 8F92-3411

Verzeichnis von d:\Daten

19.12.2005 19:53 26 test
1 Datei(en) 26 Bytes
0 Verzeichnis(se), 773.840.896 Bytes frei

Dieser Output wird als Textdatei "temp.dat" irgendwohin geschrieben.

Aber, was macht der Rest (for tokens... delims... %%i in...?

Von dieser Zwischendatei wiederum ist für den Batch nur eine Zeile interessant, die Zeile mit dem Dateinamen "test" . Diese Zeile holt er mit dem "findstr TEST temp.dat".

...aus dieser Zeile wiederum will der Autor die Stunden und Minuten rausfieseln. Dazu gibt er dem FOR /F IN..DO..-Befehl die Anweisung
Trenne den Inhalt der Zeile 19.12.2005 19:53 26 test
in "Tokens" (Einzelteile, Elemente..) und fasse Doppelpunkt und SPACE als Trennzeichen auf.
Und nimm davon die Tokens 1,2 und 3 ...der Rest kann in die Tonne.
"tokens=1,2,3 delims=: "
19.12.2005 19:53 26 test--------> nach dieser Regel ergibt:
19.12.2005 ist Token1
19 (die 19 von der Uhrzeit) ist Token 2
53 (die Minuten) ist Token 3
<s> 26 test</s> wird nicht beachtet; sind die Token 4 und 5

und wofür stehen dabei %%i %%j %%k?)

Diese drei Token werden über automatisch generierte Zählvariablen "transportiert", von denen nur die erste definiert werden muss. Der Autor hat %%i als Zählvariable genommen.
Also:
Token1----> kommt "hinter dem ..DO.." an als %%i .......Inhalt "19.12.2005"
Token2----> kommt "hinter dem ..DO.." an als %%j........Inhalt "19" (Stunden)
Token3----> kommt "hinter dem ..DO.." an als %%k.......Inhalt "53" (Minuten)

Mit diesen Werten wird eine "Subroutine" namens ":SUB" gerufen.
Diese :SUB kennt natürlich nicht diese ganze Vorgeschichte und will sie auch gar nicht wissen.. diese :SUB "weiß" nur: Sie bekommt drei Parameter übergeben.
Die heißen dann der Einfachheit halber %1, %2, %3..


Am Ende wird dann eine SUB aufgerufen, ...
So, dann kommt noch in der SUB etwas, dass ich auch nicht verstehe...
..das geht mir auch so...kopfschüttel

SchnipselSubRoutine
:SUB
SET DSTUNDE=%2 && ----------------->der zweite Parameter wird als DSTUNDE gespeichert; Wert ="19"
SET DMINUTE=%3 && ------------------>der dritte Parameter wird als DMINUTE gespeichert; Wert ="53"
:: Jetzt kommt nur Quatsch.............
SET JAHR=%date:~-2% && vom aktuellen, nicht vom Datei-Datum die letzten beiden Zeichen (z.B. "05")
SET MONAT=%date:~3,2% && vom aktuellen, nicht vom Datei-Datum ab Zeichen 3 zwei Zeichen (z.B. "12")
SET TAG=%date:~0,2% && vom aktuellen, nicht vom Datei-Datum ab Beginn zwei Zeichen (z.B. "19")
<s>rem SET STUNDE=%time:~0,2%
rem SET MINUTE=%time:~3,2% </s>
SET NEWFILENAME=%MONAT%%TAG%%DSTUNDE%%DMINUTE%.%JAHR%
:: Somit wird der neue Dateiname aus Tagesdatum (heute) und der Datei-Uhrzeit zusammengemanscht *kopfschüttel*
ren "D:\DATEN\Test" "%NEWFILENAME%"
::???????hatten wir nicht den Namen "test" in einer Variablen %FileName%????
del "D:\DATEN\temp.dat"
SchnipselSubRoutine
vom inhaltlichen Schwachsinn abgesehen: works as designed, wie wir Biber sagen..*fg

HTH Biber
P.S. Im Bereich "Batch & Shell" gibt es auch ein Tutorial zum Thema "Datums- und Zeitvariablen im Batch" und auch ein paar Batch-Grundlagen.
Member: mkdeluxe
mkdeluxe Dec 20, 2005 at 07:13:25 (UTC)
Goto Top
Hallo drop_ch und Biber,

vielen lieben Dank für die Erklärung!!! Wenigstens weiß ich jetzt WAS da passiert, jetzt muss ich nur noch rausfinden warum... Aber das müssen mir die entsprechenden Leute mal schön selbst erklären!!!

...vom inhaltlichen Schwachsinn abgesehen:...

Danke, das wollte ich hören! face-wink

Ihr habt mir wirklich sehr geholfen!!!
THX mkdeluxe
Member: Biber
Solution Biber Dec 20, 2005, updated at Feb 19, 2015 at 16:01:18 (UTC)
Goto Top
Na, mkdeluxe,

dann poste doch jetzt bitte die kleine Anekdote, die sich hinter Deiner Frage bzw. hinter diesem Praktikanten-Schnipsel verbirgt... neugierig bin ich ja auch.. und sieht so aus, als hättest Du da auch noch eine kleine Pointe auf Lager...

Grüße Biber
Member: mkdeluxe
mkdeluxe Dec 22, 2005 at 11:43:38 (UTC)
Goto Top
Hallo Biber,

habe die Antwort gerade erst gesehen...

Unser Admin sagt er braucht das aktuelle Datum weil er ja wissen muss wann die Datei umgestellt wurde. Er konnte mir jedoch nicht so genau erklären, wozu die Uhrzeit der Originaldatei dann notwendig ist. Und warum das aktuelle Datum nötig ist wusste er eigentlich auch nicht, denn eigentlich wäre das Erstellungsdatum ja wesentlich wichtiger. Er hat das jedoch nicht selbst geschrieben, und der Verfasser arbeitet inzwischen nicht mehr hier... Warum nur...???

Grüße mkdeluxe
Member: Biber
Solution Biber Dec 22, 2005, updated at Feb 19, 2015 at 16:01:22 (UTC)
Goto Top
*lacht*
Danke, mkdeluxe,

dachte mir schon so etwas ähnliches.. face-wink

Ich denke, nach den ausführlichen Erläuterungen könntest Du den Schnipsel oben auch geradebiegen- im Moment ist es ja nur Unsinn, was der macht. Aber im Bereich "Batch & Shell" findest Du auch schnell besser gelöste Beispiele zum Thema Logdatei mit Datum etc. Oder in den Tutorials.

IMHO gilt aber auch für Batchdateien (auch wenn die meisten Batch ja nicht als Programmier-Werkzeug ernstnehmen):
Kommentare im Code und Dokumentation müssen sein.
Und das fand und finde ich das Schlimmste an dem von Dir geposteten Beispiel - viel schlimmer als handwerkliche Schnitzer und Schmunzelbugs.
Immerhin ist das Dingens ja in produktive innerbetriebliche Abläufe eingebunden.

Platz genug ist in jeder *.bat-Datei für Kommentare - selbst ein einzeiliger Batch belegt heutzutage 16.364 Byte auf der Platte.. also: was soll der Geiz?

Vielen Dank für die Rückmeldung
Biber