koyote
Goto Top

Set-Befehl innerhalb einer Schleife funktioniert nicht wie erwartet

Hallo Experten,

mit folgendem Problem schlage ich mich seid Tagen herum und komme einfach nicht weiter. Und zwar möchte ich innerhalb einer Schleife eine Textdatei zeilenweise auslesen. Aus der jeweiligen Zeile soll ein bestimmter String extrahiert und über die Konsole ausgegeben werden. Die Entwicklung erfolgt auf einer Rechner mit Windows XP SP2.


Inhalt der Datei "test.txt":
3 Datei(en) 1.245.247 Bytes
1 Datei(en) 2.902.052 Bytes


Inhalt der Batchdatei:
for /f "tokens=1 delims=;" %%j in (c:\temp\test.txt) do (
set v1=%%j
set v2=%v1:*Datei(en)=%
echo %v2%
)
pause

Gewünschtes Ergebnis soll sein:
1.245.247 Bytes
2.902.052 Bytes

Jedoch erhalte ich als Ausgabe:
*Datei(en


Ich vermute, dass das Problem im Zusammenhang mit dem "set"-Befehl innerhalb der Schleife liegt, da der Befehl außerhalb einer Schleife erfolgreich ausgeführt wird.

Für einen Tip bin ich dankbar!


Zusatz:
Eine Lösung konnte ich mittlerweile finden, indem ich mit dem CALL-Befehl die Stringextraktion außerhalb der Schleife durchführe. Aber vielleicht gibt es noch eine elegantere Lösung.


Inhalt der Batchdatei:
for /f "tokens=1 delims=;" %%j in (c:\temp\test.txt) do (
set v1=%%j
call :prozedur
)
pause

:prozedur
set v2=%v1:*Datei(en)=%
echo %v2%

Content-Key: 80478

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

Ausgedruckt am: 28.03.2024 um 22:03 Uhr

Mitglied: bastla
bastla 11.02.2008 um 17:20:07 Uhr
Goto Top
Hallo Koyote!

Deine gefundene Lösung ist nicht wirklich unelegant - aber Du kannst das Unterprogramm auch so vermeiden:
for /f "tokens=2*" %%j in (c:\temp\test.txt) do echo %%k  

Grüße
bastla
Mitglied: miniversum
miniversum 11.02.2008 um 17:32:34 Uhr
Goto Top
Ja das liegt daran das die Auflösung von Variabeln in Schleifen ncith geht. Da kan man eben entweder so wie Du machen indem man es in eine Extra Prozedur umleitet oder mit delayedexpansion arbeitet.

Eleganter wäre das ganze doch wenn ich das richtig verstehe einfach so:
for /f "tokens=2* delims= " %%j in (c:\temp\test.txt) do echo %%k
Mitglied: bastla
bastla 11.02.2008 um 18:33:45 Uhr
Goto Top
... um vielleicht auch die Verwendung der angesprochenen "delayedexpansion" zu demonstrieren:
@echo off & setlocal enabledelayedexpansion
for /f "delims=" %%j in (cs:\temp\test.txt) do (  
	set "v1=%%j"  
	set "v2=!v1:*Datei(en)=!"  
	echo !v2!
)
pause
Nachteil dieser Vorgangsweise (allerdings hier vermutlich zu vernachlässigen): In den Daten enthaltene "!" gehen verloren, sind in einer Zeile sogar zwei "!", verschwindet auch der Text dazwischen.

Grüße
bastla
Mitglied: Koyote
Koyote 12.02.2008 um 14:57:03 Uhr
Goto Top
Danke für die schnellen Rückmeldungen. Diese konnten auf jeden Fall meine große Leere übers Batchen ein weinig füllen. Aber wie das nunmal beim Programmieren so ist, habe ich dieses Problem bereits abgehackt und bin dafür auf ein neues gestoßen.

Eigentlich müsste ich dafür einen neuen Thread öffnen, aber vielleicht lässt dieses sich auch hier lösen.

Und zwar geht es um Rechenoperationen mit Zahlen größer 32 Bit. Einen Lösungsansatz konnte ich dem Thread "freien Festplattenspeicher über die Kommandozeile abfragen" entnehmen. Genauer geht es um das vom Biber eingestellte Batch:


Biber 04.04.2006 ##############

::------snipp getfreespace.bat
@echo off & setlocal enabledelayedexpansion
@for %%a in (%*) do @for /f "tokens=3" %%i in ('dir /-c %%a:^|find /i "Bytes fre"') do call :calc %%a %%i
goto disp
:calc
(Set "Dim=GigaByte") & (set fs_drive%1=%1) & set fs_space=%2
set /a fs_space=%fs_space:~0,-9%+0
if %fs_space% == 0 (set /a fs_space=%2/1024) && set "Dim=KByte"
if [%Dim%]==[KByte] if %fs_space% GTR 1024 (set /a fs_space/=1024) && set "Dim=MByte"
if [%Dim%]==[GigaByte] if %fs_space% GTR 1024 (set /a fs_space/=1024) && set "Dim=TeraByte"
if [%Dim%]==[GigaByte] if %fs_space% GTR 1024 (set /a fs_space/=1024) && set "Dim=PetaByte"
set "fs_space%1=%fs_space% %dim% frei"
goto :eof

:disp
For %%i in (%*) do echo Laufwerk !fs_drive%%i!:\ !fs_space%%i!
::------snapp getfreespace.bat

Biber 04.04.2006 ##############


Soweit ich dieses richtig verstehe, wird vor der weiteren Verwendung einer Variabel als Zahl, diese zuvor mit

--- set /a fs_space=%fs_space:~0,-9%+0 --- und
--- if %fs_space% == 0 ---

geprüft. Nicht nachvollziehen kann ich, wie das Programm mit Zahlen größer 32 Bit umgeht.

Für jeden Tip bin ich dankbar!
Mitglied: miniversum
miniversum 12.02.2008 um 15:21:26 Uhr
Goto Top
In dieser Batch wird ja die Anzeige der freien Bytes vom Dir Befehl benutzt.
Das ist dann eine Zahl beliebiger Länge, z.B. 13967048704
Diese Zahl wird dann als Textstring weiter verarbeitet.
die in meinem Beispiel verwendete Zahl ist ja in der Einheit B. In GB wäre das (groß) einfach das gleiche wenn man die letzten 9 Stellen entfernt, also 13 GB.
Der Befehl
set fs_space=%fs_space:~0,-9%
Würde dies damit erledigen.

der hier Verwendete zusatz mit /a und der +0 macht zusätzlich aus dem Textstring eine Zahl die man dann auf größer und kleiner prüfen kann.
Wäre also die Zahl nach dem Abschneiden der letzten 9 Stellen = 0 würde das also Bedeuten das die zahl kleiner einem GB ist. Daher diese kontrolle mit
if %fs_space% == 0 ..

miniversum
Mitglied: Koyote
Koyote 12.02.2008 um 16:08:02 Uhr
Goto Top
Danke für die super schnelle Antwort.

D.h. also man muss diesem Fall mit Unschärfen leben.
Zum Beispiel:

75161927680 Bytes entsprechen 70 GigaByte, wobei das Batch 75 GigaByte ausgeben würde.
Mitglied: miniversum
miniversum 12.02.2008 um 16:16:47 Uhr
Goto Top
Ja.
Alternativ gibt es in dem Posting glaube ich auch ein VBS skript was das genau kann.

miniversum