How do I increment a DOS variable in a FOR /F loop

2019-01-21 18:52发布

I'm trying to read text lines from a file, and increment a counter so I can eventually simulate an array in DOS.

I'd like to be able to store the lines of text in a DOS array for further processing.

My current attempt is:

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%
)

But the variable c is not incrementing; it stays at 1.

Suggestions welcome.

Thanks, Mike

标签: arrays dos
6条回答
迷人小祖宗
2楼-- · 2019-01-21 19:13

The problem with your code snippet is the way variables are expanded. Variable expansion is usually done when a statement is first read. In your case the whole FOR loop and its block is read and all variables, except the loop variables are expanded to their current value.

This means %c% in your echo %%i, %c% expanded instantly and so is actually used as echo %%i, 1 in each loop iteration.

So what you need is the delayed variable expansion. Find some good explanation about it here.

Variables that should be delay expanded are referenced with !VARIABLE! instead of %VARIABLE%. But you need to activate this feature with setlocal ENABLEDELAYEDEXPANSION and reset it with a matching endlocal.

Your modified code would look something like that:

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
查看更多
女痞
3楼-- · 2019-01-21 19:14

What about this simple code, works for me and on Windows 7

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

:end
查看更多
Deceive 欺骗
4楼-- · 2019-01-21 19:17

Using Windows 7. Can't get the EnableDelayedExpansion to do its thing. I have two test files called Test1.tst and Test2.tst. I want to do something with only the first one. The two places I the '!' doesn't resolved to the value. The last echo prints zero. Here is my 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
查看更多
做个烂人
5楼-- · 2019-01-21 19:21
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%
)
查看更多
The star\"
6楼-- · 2019-01-21 19:28

Or you can do this without using Delay.

set /a "counter=0"

-> your for loop here

do (
   statement1
   statement2
   call :increaseby1
 )

:increaseby1
set /a "counter+=1"
查看更多
狗以群分
7楼-- · 2019-01-21 19:35

I would like to add that in case in you create local variables within the loop, they need to be expanded using the bang(!) notation as well. Extending the example at https://stackoverflow.com/a/2919699 above, if we want to create counter-based output filenames

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
查看更多
登录 后发表回答