Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

FOR loop not incrementing value until after loop exits

3 views
Skip to first unread message

keneo

unread,
Nov 25, 2009, 5:59:02 PM11/25/09
to
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?

Frank P. Westlake

unread,
Nov 25, 2009, 6:12:44 PM11/25/09
to
"keneo"
news:1b210e23-706b-4fc6...@d21g2000yqn.googlegroups.com...

> ...(


> SET /a I+=1
> ECHO I=%I%
> IF %I% GTR 3 ( MOVE "%%A" OLD )
> )

> ... the value of %I% stays unchanged

CMD in line oriented. It reads an entire line and and replaces
environment variables before executing the script in the line.
Everything within parentheses is considered one line. This is
old-fashioned behavior of variables with MSDOS. Think of it as "pasting"
the value into the line.

The variable is modified as you use it but your value was pasted in
before you modified it.

There is a new behavior available since after NT4; it is called delayed
expansion. Delayed expansion variables are identified with exclamation
marks instead of percent signs: !I! instead of %I%. Delayed expansion
might be enabled by the Registry of by a switch of CMD.EXE, but to
ensure that it is enabled for your script use the ENABLEDELAYEDEXPANSION
parameter of SetLocal.

Using delayed expansion will cause CMD to read the value each time the
variable is used.

REF:
SETLOCAL /?
CMD /?

Frank


billious

unread,
Nov 25, 2009, 7:19:51 PM11/25/09
to

"keneo" <kka...@gmail.com> wrote in message
news:1b210e23-706b-4fc6...@d21g2000yqn.googlegroups.com...

About time we held new elections for #1 FAQ, I believe.

Timo Salmi publishes the FAQ every Monday, regular as clockwork. As if it
was scheduled automatically.

The fundamental feature involved is that any %var% in the entire logical
command, from the FOR its closing parenthesis, is replaced by its current
value at PARSE time and THEN the FOR is executed.

There is more than one solution. The most common would probably be to invoke
'delayedexpansion' mode.

Place a

SETLOCAL ENABLEDELAYEDEXPANSION

line before the FOR

AND then use the !var! syntax in place of %var%. !var! will be the run-time
value.

eg:


setlocal enabledelayedexpansion
set var=original
for %%f in (1 2 3 4) do set var=%%f&echo %%f+%var%+!var!+

- try this line-sequence with and without the SETLOCAL line.

See

SETLOCAL /?

from the prompt for more docco - or see past responses in this ng. Note that
you may also need to use the ENABLEEXTENSIONS switch also.

As to a better way -

Try reversing the sort order by using /OD rather tha /o-d AND add SKIP=3
before the 'tokens=' in the FOR options. That way, the 3 NEWEST files are
skipped and you can dispose of the I variable.


Todd Vargo

unread,
Nov 25, 2009, 10:23:14 PM11/25/09
to

billious wrote:
> keneo wrote:
snip...

> > 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.
snip...

>
> About time we held new elections for #1 FAQ, I believe.

I had the exact same thought in mind when I read OP's post.

--
Todd Vargo
(Post questions to group only. Remove "z" to email personal messages)

Ted Davis

unread,
Nov 26, 2009, 10:42:00 AM11/26/09
to
On Wed, 25 Nov 2009 22:23:14 -0500, Todd Vargo wrote:


> billious wrote:
>> keneo wrote:
> snip...
>> > 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.
> snip...
>>
>> About time we held new elections for #1 FAQ, I believe.
>
> I had the exact same thought in mind when I read OP's post.

If they don't read the /? help (for SET), don't search the groups and the
web for answers, and multipost the question, is there any point in even
having a FAQ?

Anyway, I think the first should be "some command doesn't do what I want -
what's wrong?" The response, of course, would be "RTFM, you idiot."

I'm not in a good mood this morning: I had to move Fluffy (one of my cats)
out of my way at least a dozen times already - she can't seem to keep her
nose out of the turkey I'm preparing for Thanksgiving dinner - and my
patience has worn very thin.

--

T.E.D. (tda...@mst.edu)


keneo

unread,
Nov 26, 2009, 10:45:00 AM11/26/09
to
Wow! You guys have taught me a lot! Thank you so very much for your
very informative answers. I never expected such detail and very
nicely explained too.

I have run into problems with this variable issue before, and I always
just worked around it. I am glad that this timeI decided to ask in
this group. This will really make things easier now

Batch works like a charm now.

Take care.

Ken

foxidrive

unread,
Nov 26, 2009, 11:00:14 AM11/26/09
to
On Thu, 26 Nov 2009 09:42:00 -0600, Ted Davis <tda...@mst.edu> wrote:

>I'm not in a good mood this morning: I had to move Fluffy (one of my cats)
>out of my way at least a dozen times already - she can't seem to keep her
>nose out of the turkey I'm preparing for Thanksgiving dinner

Enjoy your Thanksgiving, Ted. (Aside to Fluffy: keep clear of the carving
knife, k?) ;-)

Timo Salmi

unread,
Nov 26, 2009, 3:27:31 PM11/26/09
to
keneo <kka...@gmail.com> wrote:
> 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

10} How can I change the environment variable values within a FOR loop?
http://www.netikka.net/tsneti/info/tscmd010.htm

158} Why won't the statements within my if condition work properly?
http://www.netikka.net/tsneti/info/tscmd158.htm

All the best, Timo

--
Prof. Timo Salmi mailto:t...@uwasa.fi ftp & http://garbo.uwasa.fi/
Hpage: http://www.uwasa.fi/laskentatoimi/english/personnel/salmitimo/
Department of Accounting and Finance, University of Vaasa, Finland
Useful CMD script tricks http://www.netikka.net/tsneti/info/tscmd.htm

Ted Davis

unread,
Nov 26, 2009, 5:09:31 PM11/26/09
to
On Fri, 27 Nov 2009 03:00:14 +1100, foxidrive wrote:

> Enjoy your Thanksgiving, Ted. (Aside to Fluffy: keep clear of the carving
> knife, k?) ;-)

I already have, a bit: Thanksgiving feasting for me is all about white
rice and giblet gravy, deviled eggs, black eye peas made from dry beans,
and, oh yes, a bit of turkey and even a piece of cake for desert - I ate
two pieces of deviled eggs before I could even get them into the fridge.
Dinner is at 6 - it's 4 now and I still have to make the gravy, but the
giblets and stock are almost ready. The turkey will be done in about an
hour, leaving time to make corn bread. I do a turkey mostly to get the
giblets and stock for the gravy - the cats will get most of the dark meat.
BTW, I'm up to 15 cats now - somebody dumped off the sweetest classic
tabby tom (now ex tom) a couple of weeks ago, so I took him in. Good
think I live in the country and have a *huge* yard that extends well back
from the road.

--

T.E.D. (tda...@mst.edu)

0 new messages