Autor Beitrag
rzwanziger
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 22



BeitragVerfasst: Di 08.09.09 13:34 
Hallo,

weiß nicht ob ich hier richtig bin... es geht um Batch-Programmierung unter Windows. Ich habe folgende Datei "list.bat":

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
@echo off

for %%f in (*.txt) do (
  set zzz=%%f
  echo %%f
  echo %zzz%
  echo.
)


Diese liegt in einem Verzeichnis zusammen mit den drei Dateien abc.txt, def.txt und ghi.txt.

Ich öffne eine command shell, wechsle in das Verzeichnis und rufe die list.bat auf. Passieren sollte eigentlich folgende Ausgabe:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
abc.txt
abc.txt

def.txt
def.txt

ghi.txt
ghi.txt

echo Fertig!


Es kommt aber anstatt dessen:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
abc.txt
ECHO is off.

def.txt
ECHO is off.

ghi.txt
ECHO is off.

echo Fertig!


Warum?
Und das beste: wenn ich anschließend in der Command-Box das Kommando "set" eingebe um mir alle Variablen anzeigen zu lassen, dann steht an letzer Stelle:

ausblenden Quelltext
1:
zzz=ghi.txt					


Erreichen will ich eigentlich, dass der Variable zzz innerhalb der Schleife jeweils der Dateiname zugewiesen wird, weil ich mit diesem dann entsprechend weiter arbeiten kann. Nach Schleifenende brauche ich die Variable nicht mehr, es kann also auch eine rein innerhalb des Skripts bekannte, lokale Variable sein.

Habe ich hier ein grundsätzliches Denkproblem?

Danke für Anregungen,
Ralf
baka0815
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 489
Erhaltene Danke: 14

Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
BeitragVerfasst: Di 08.09.09 13:53 
Sieht so aus als wäre der PC zu schnell.

Wenn ich das ganze mit Pause verbinde:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
@echo off

for %%f in (*.txt) do (
  set zzz=%%f
  echo %%f
  pause
  echo %zzz%
  echo.
)


Und dann eben immer [ENTER] drücke, bekomme ich folgende Ausgabe:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
>test
abc.txt
Drücken Sie eine beliebige Taste . . .
ghi.txt

def.txt
Drücken Sie eine beliebige Taste . . .
ghi.txt

ghi.txt
Drücken Sie eine beliebige Taste . . .
ghi.txt


Ohne die Pause dazwischen bekomme ich das gleiche Ergebnis wie du.
rzwanziger Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 22



BeitragVerfasst: Di 08.09.09 14:16 
Nein, das kann nicht hinhauen, denn Dein zweiter Dateiname ist immer ghi.txt.

Du hast denselben Effekt wie ich: nach dem ersten Durchlauf ist in der Shell die Variable zzz gesetzt, und zwar, ich nenne es mal: "shell-global". Gib mal "set" ohne Parameter ein, dann siehst Du das.

Ich habe das Programm jetzt dahingehend umgewandelt, dass ich innerhalb der Schleife jeweils ein Unterprogramm aufrufe und %%f übergebe - damit klappt es. Ich habe allerdings keine Ahnung, warum. Hier der Programmcode:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
@echo off

for %%f in (*.txt) do (
  echo %%f
  call :dateiverarbeiten %%f
  echo.
)
goto :ende

:dateiverarbeiten
set zzz=%1
echo Dateiname ist %zzz%
goto :eof

:ende
echo Fertig!


und der Output:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
D:\src>list
abc.txt
Dateiname ist abc.txt

def.txt
Dateiname ist def.txt

ghi.txt
Dateiname ist ghi.txt

Fertig!
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10185
Erhaltene Danke: 1261

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Di 08.09.09 15:14 
Moin!

'help cmd' hat folgendes geschrieben:
Die verzögerte Umgebungsvariablenerweiterung ist standardmäßig NICHT aktiviert.
Die verzögerte Umgebungsvariablenerweiterung kann unter Verwendung der Option
"/V:ON" oder "/V:OFF" für einen bestimmten Aufruf von CMD.EXE
aktiviert bzw. deaktiviert werden. Die verzögerte Umgebungsvariablenerweiterung
kann auch für alle Aufrufe des Befehlsprozessors deaktiviert werden, indem
einer oder beide der folgenden Werte in der Registrierung auf 0x1 oder 0x0
gesetzt werden (unter Verwendung von REGEDT32.EXE):

HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\DelayedExpansion

und/oder

HKEY_CURRENT_USER\Software\Microsoft\Command Processor\DelayedExpansion

[...]
Bei aktivierter verzögerter Umgebungsvariablenerweiterung kann das
Ausrufezeichen dazu verwendet werden, den Wert einer Umgebungsvariable zur
Laufzeit zu ersetzen.
Das hatte irgendwas damit zu tun, glaub ich. :? Ich fall da aber auch immer wieder drauf rein... :roll:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Di 08.09.09 16:07 
Nope, das Problem ist eine ganz einfache Geschichte: Die CMD wertet Variablen mit % so früh es geht aus. Wenn du also in einer Schleife eine Variable brauchst, die je Schleifendurchlauf anders ist, so musst du diese mit !zzz! verwenden (statt %zzz%).

Daher bekommst du auch einen Leerstring respektive den letzten gelisteten Dateinamen: Die Variable wird bereits am Anfang des Scripts ausgewertet und ersetzt, durch das, was bereits drin steht. die Sets werden dann aber durchgeführt; aber nicht mehr sichtbar, da es die Platzhalter nicht mehr gibt.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
rzwanziger Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 22



BeitragVerfasst: Mi 09.09.09 07:20 
Zitat:
Wenn du also in einer Schleife eine Variable brauchst, die je Schleifendurchlauf anders ist, so musst du diese mit !zzz! verwenden (statt %zzz%).


Hmm, also so?

ausblenden Quelltext
1:
2:
3:
  echo %%f
  set zzz=%%f
  echo !zzz!


Das klappt aber nicht, dann gibt die shell "!zzz!" aus (den String, nicht den Inhalt) :(
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Mi 09.09.09 09:13 
Erweiterte Syntax under verzögerte Variablen-Auswertung der CMD aktiviert? Die braucht man dazu. Ansonsten müsste ich das auch kurz ausprobieren, wann man das wie setzen muss ... Ist immer etwas gefrickel.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
rzwanziger Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 22



BeitragVerfasst: Mi 09.09.09 10:15 
Ah, das war der Fehler. Vielen Dank!!
baka0815
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 489
Erhaltene Danke: 14

Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
BeitragVerfasst: Mi 09.09.09 10:16 
Jupp, stimmt. Hatte nicht genau auf die ausgabe geguckt, sondern nur gesehen, dass nicht "echo ist ausgeschaltet" kommt. :)

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
> type test.bat
@echo off

for %%f in (*.txt) do (
  set zzz=%%f
  echo %%f
  echo !zzz!
  echo.
)

> test.bat
abc.txt
!zzz!

def.txt
!zzz!

ghi.txt
!zzz!

> cmd /V:On /c test.bat
abc.txt
abc.txt

def.txt
def.txt

ghi.txt
ghi.txt