2010-05-26 4 views
38

Ich versuche, Textzeilen aus einer Datei zu lesen, und einen Zähler inkrementieren, damit ich schließlich ein Array in DOS simulieren kann.Wie inkrementiere ich eine DOS-Variable in einer FOR/F-Schleife?

Ich möchte in der Lage sein, die Zeilen Text in einem DOS-Array für die weitere Verarbeitung zu speichern.

Mein aktueller Versuch ist:

set TEXT_T="myfile.txt" 

set /a c=1 

FOR /F "tokens=1 usebackq" %%i in (%TEXT_T%) do (
set /a c=c+1 
echo %%i, %c% 
) 

Aber die Variable c ist Inkrementieren nicht; es bleibt bei 1.

Vorschläge willkommen.

Dank, Mike

Antwort

72

Das Problem mit dem Code-Snippet ist die Art und Weise Variablen erweitert werden. Die variable Erweiterung wird normalerweise durchgeführt, wenn eine Anweisung zuerst gelesen wird. In Ihrem Fall wird die ganze FOR Schleife und ihr Block gelesen und alle Variablen außer den Schleifenvariablen werden auf ihren aktuellen Wert erweitert.

Dies bedeutet %c% in Ihrem echo %%i, %c% sofort erweitert und so wird tatsächlich als echo %%i, 1 in jeder Schleife Iteration verwendet.

Was Sie also brauchen, ist die verzögerte variable Expansion. Finden Sie eine gute Erklärung dazu here.

Variablen, die verzögert erweitert werden sollen, werden mit !VARIABLE! statt %VARIABLE% referenziert. Sie müssen diese Funktion jedoch mit setlocal ENABLEDELAYEDEXPANSION aktivieren und mit einem passenden endlocal zurücksetzen.

Ihre modifizierte Code würde so ähnlich aussehen:

set TEXT_T="myfile.txt" 

set /a c=1 

setlocal ENABLEDELAYEDEXPANSION 

FOR /F "tokens=1 usebackq" %%i in (%TEXT_T%) do (
    set /a c=c+1 

    echo %%i, !c! 
) 

endlocal 
+0

SuperDuper! Genau das habe ich gebraucht. Ich änderte das Skript entsprechend und es läuft jetzt wie erwartet. Danke für die schnelle Antwort. - Mike – Mike

+3

@Mike: Sie sollten diese Antwort als akzeptiert markieren, wenn es Ihr Problem gelöst hat! – Sk8erPeter

+0

@Frank Bollack. Vielen Dank für diese Erklärung, ich habe etwas Neues gelernt. Ich benutzte diese Technik, um diese andere Frage zu beantworten: http://serverfault.com/questions/664202/batch-file-that-kills-a-certain-process. Es funktioniert, aber ich bin mir nicht sicher, wie ich die Variablen außerhalb der FOR-Schleife referenzieren sollte. Macht es einen Unterschied, mit! C! oder% c%, wenn ich nach dem FOR habe? – pgr

3

Ich möchte, dass im Falle hinzuzufügen in Sie lokale Variablen innerhalb der Schleife erstellen, müssen sie den Knall erweitert werden mit Bezeichnungen wie (!) Gut. Die Erweiterung des Beispiel bei https://stackoverflow.com/a/2919699 oben, wenn wir zählerbasierten Ausgabedateinamen

set TEXT_T="myfile.txt" 

set /a c=1 

setlocal ENABLEDELAYEDEXPANSION 

FOR /F "tokens=1 usebackq" %%i in (%TEXT_T%) do (
    set /a c=c+1 
    set OUTPUT_FILE_NAME=output_!c!.txt 
    echo Output file is !OUTPUT_FILE_NAME! 
    echo %%i, !c! 
) 

endlocal 
2

Oder Sie können dies tun, ohne Verzögerung erstellt werden soll.

set /a "counter=0" 

-> Ihre for-Schleife hier

do (
    statement1 
    statement2 
    call :increaseby1 
) 

:increaseby1 
set /a "counter+=1" 
0
set TEXT_T="myfile.txt" 
set /a c=1 

FOR /F "tokens=1 usebackq" %%i in (%TEXT_T%) do (
    set /a c+=1 
    set OUTPUT_FILE_NAME=output_%c%.txt 
    echo Output file is %OUTPUT_FILE_NAME% 
    echo %%i, %c% 
) 
0

Verwendung von Windows 7. Kann nicht die EnableDelayedExpansion bekommen seine Sache zu tun. Ich habe zwei Testdateien namens Test1.tst und Test2.tst. Ich möchte etwas nur mit dem ersten machen. Die zwei Orte, die ich '!' wird nicht auf den Wert aufgelöst. Die letzte echo druckt Null. Hier ist mein Code:

set /a count1=0 

setlocal EnableDelayedExpansion 
for %%x in (*.tst) do (

    if !count1! GTR 0 goto :getout 

    call :addit 

    type %%x 

    ren %%x *.xxx 

) 
@echo Almost done... 
goto :alldone 

:addit 
set /a count1=%count1% + 1 
@echo %count1% 
goto :eof 

:getout 
@echo Getting out... 
@echo !count! 

:alldone 
endlocal 
-1

Was ist mit diesem einfachen Code, funktioniert für mich und auf Windows 7

set cntr=1 
:begin 
echo %cntr% 
set /a cntr=%cntr%+1 
if %cntr% EQU 1000 goto end 
goto begin 

:end