FOR loop not incrementing value until after loop exits

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
keneo
Posts: 5
Joined: 12 Oct 2009 16:50

FOR loop not incrementing value until after loop exits

#1 Post by keneo » 25 Nov 2009 16:15

I am trying to write a batch file that will iterate through the files in a folder. As soon as it hits the 4th one (and subsequent ones) it will move that file to a sub directory "OLD." Since I order the DIR command by date it will only leave the 3 newest files untouched in the folder.

here is what I have...

@ECHO OFF

CD C:\AVI\

FOR /F "tokens=*" %%A IN ('DIR c:\AVI\*.AVI /b /a-d /o-d') do (
SET /a I+=1
ECHO I=%I%
IF %I% GTR 3 ( MOVE "%%A" OLD )
)

echo count = %I%

The problem is that for some reason the value of %I% stays unchanged until after the FOR loop is completed. Within the loop the echo statement ECHO I=%I% always returns 'I=0'. Since %I% is zero the conditional never executes the MOVE command.

Strangely, after the loop exits the %I% variable suddenly decides to co-operate and returns the proper file count. There are 5 files in the folder so the echo command returns 'count = 5'

can someone fix this? or give me an alternative solution?

avery_larry
Expert
Posts: 391
Joined: 19 Mar 2009 08:47
Location: Iowa

#2 Post by avery_larry » 26 Nov 2009 11:03

It's a classic delayed variable expansion problem. Any variable inside a for loop will only be evaluated at the time the for loop is called, so subsequent loops of the for loop will NOT get any updated values.

You need to use delayedexpansion like this:

Code: Select all

@ECHO OFF
setlocal enabledelayedexpansion

CD C:\AVI\
set "I=0"
FOR /F "tokens=*" %%A IN ('DIR c:\AVI\*.AVI /b /a-d /o-d') do (
   SET /a I+=1
   ECHO I=!I!
   IF !I! GTR 3 ( MOVE "%%A" OLD )
)

echo count = %I%


Of course, you could probably just use the skip feature of the for loop like this:

Code: Select all

@ECHO OFF

CD C:\AVI\
set "I=3"
FOR /F "skip=3 tokens=*" %%A IN ('DIR c:\AVI\*.AVI /b /a-d /o-d') do (
   SET /a I+=1
   MOVE "%%A" OLD
)

echo count = %I%

Post Reply