for loop variable insanity

  • Thread starter Thread starter emrefan
  • Start date Start date
E

emrefan

Guest
I wanted to write a batch file for comparing files in the current
directory with those in another directory in terms of file size. And
the following is what I have so far:

@echo off
rem compare files in the current directory with those in another
directory
rem in terms of file size.
rem parameter to this batch ("the other directory") should include the
path separator
rem (backslash) if it is a proper directory spec rather than say
"<drive letter>:"

if "%1"=="" (
echo Usage %0 the-other-dir
goto :end
)

for %%f in (*.*) do (
set fn=%%f
echo %fn%
set fn2=%1%fn%
echo %fn%

for %%G in (%fn%) do set fz1=%%~zG
for %%H in (%fn2%) do set fz2=%%~zH
echo fz1=%fz1% fz2=%fz2%
)

:end

Now, every time I ran this batch file only things from the stupid to
the absolute insane happened. The results did not make any sense at
all. Sometimes the file sizes were insanely large, sometimes empty,
other times the filenames fetched were those from the last run and
were totally irrelevant to the recent invocation. I think the fact I
am assigning the for loop variable to another variable is making XP go
berserk because if I had the for loop modified to this below things
would appear normal.

for %%f in (*.*) do echo %%~zf

But of course that's not gonna get my job done. :(
 
Re: for loop variable insanity


"emrefan" <dksleung@hotmail.com> wrote in message
news:bf41fc7a-7b44-411f-acb1-31eed21f3ca4@p10g2000prf.googlegroups.com...
>I wanted to write a batch file for comparing files in the current
> directory with those in another directory in terms of file size. And
> the following is what I have so far:
>
> @echo off
> rem compare files in the current directory with those in another
> directory
> rem in terms of file size.
> rem parameter to this batch ("the other directory") should include the
> path separator
> rem (backslash) if it is a proper directory spec rather than say
> "<drive letter>:"
>
> if "%1"=="" (
> echo Usage %0 the-other-dir
> goto :end
> )
>
> for %%f in (*.*) do (
> set fn=%%f
> echo %fn%
> set fn2=%1%fn%
> echo %fn%
>
> for %%G in (%fn%) do set fz1=%%~zG
> for %%H in (%fn2%) do set fz2=%%~zH
> echo fz1=%fz1% fz2=%fz2%
> )
>
> :end
>
> Now, every time I ran this batch file only things from the stupid to
> the absolute insane happened. The results did not make any sense at
> all. Sometimes the file sizes were insanely large, sometimes empty,
> other times the filenames fetched were those from the last run and
> were totally irrelevant to the recent invocation. I think the fact I
> am assigning the for loop variable to another variable is making XP go
> berserk because if I had the for loop modified to this below things
> would appear normal.
>
> for %%f in (*.*) do echo %%~zf
>
> But of course that's not gonna get my job done. :(


Ah, the old environmental variable trap. You need to be aware that the code
interpreter will scan single statement of the form
for %%f in (*.*) do (
set fn=%%f
echo %fn%
set fn2=%1%fn%
echo %fn%
)
exactly once. The emphasis is on "single", because the two brackets cause
these five lines of code to be treated as one single line of code. At the
initial scan time, the variable "%fn%" is not defined, hence echoing it to
the screen will give you nothing!

To get around the problem, you must instruct the interpreter to scan
multiple-line statements one at a time, not as a block. Here is how it's
done. Note the exclamation marks!

@echo off
setlocal EnableDelayedExpansion

for %%f in (*.*) do (
set fn=%%f
echo !fn!
set fn2=%1%fn%
echo !fn!
)
echo %fn%
 
Re: for loop variable insanity

On Sep 12, 2:14 pm, "Pegasus \(MVP\)" <I....@fly.com.oz> wrote:
> "emrefan" <dksle...@hotmail.com> wrote in message
> > Now, every time I ran this batch file only things from the stupid to
> > the absolute insane happened. The results did not make any sense at
> > all. Sometimes the file sizes were insanely large, sometimes empty,
> > other times the filenames fetched were those from the last run and
> > were totally irrelevant to the recent invocation. I think the fact I
> > am assigning the for loop variable to another variable is making XP go
> > berserk because if I had the for loop modified to this below things
> > would appear normal.

>
> > for %%f in (*.*) do echo %%~zf

>
> > But of course that's not gonna get my job done. :(

>
> Ah, the old environmental variable trap. You need to be aware that the code
> interpreter will scan single statement of the form
> for %%f in (*.*) do (
>   set fn=%%f
>   echo %fn%
>   set fn2=%1%fn%
>   echo %fn%
> )
> exactly once. The emphasis is on "single", because the two brackets cause
> these five lines of code to be treated as one single line of code. At the
> initial scan time, the variable "%fn%" is not defined, hence echoing it to
> the screen will give you nothing!
>
> To get around the problem, you must instruct the interpreter to scan
> multiple-line statements one at a time, not as a block. Here is how it's
> done. Note the exclamation marks!
>
> @echo off
> setlocal EnableDelayedExpansion
>
> for %%f in (*.*) do (
>   set fn=%%f
>   echo !fn!
>   set fn2=%1%fn%
>   echo !fn!
> )
> echo %fn%- Hide quoted text -


Thanks for the patience with this newbie. It was kinda surprising to
me. I wish MS would make it easier for us in their newer software
(Vista?). It's counter-intuitive to say the least, very likely to
trap up people coming over from other shell environments.
 
Re: for loop variable insanity


"emrefan" <dksleung@hotmail.com> wrote in message
news:1f37e305-22fd-42a8-958d-fca3d4fa3eee@s28g2000prd.googlegroups.com...
On Sep 12, 2:14 pm, "Pegasus \(MVP\)" <I....@fly.com.oz> wrote:
> "emrefan" <dksle...@hotmail.com> wrote in message
> > Now, every time I ran this batch file only things from the stupid to
> > the absolute insane happened. The results did not make any sense at
> > all. Sometimes the file sizes were insanely large, sometimes empty,
> > other times the filenames fetched were those from the last run and
> > were totally irrelevant to the recent invocation. I think the fact I
> > am assigning the for loop variable to another variable is making XP go
> > berserk because if I had the for loop modified to this below things
> > would appear normal.

>
> > for %%f in (*.*) do echo %%~zf

>
> > But of course that's not gonna get my job done. :(

>
> Ah, the old environmental variable trap. You need to be aware that the
> code
> interpreter will scan single statement of the form
> for %%f in (*.*) do (
> set fn=%%f
> echo %fn%
> set fn2=%1%fn%
> echo %fn%
> )
> exactly once. The emphasis is on "single", because the two brackets cause
> these five lines of code to be treated as one single line of code. At the
> initial scan time, the variable "%fn%" is not defined, hence echoing it to
> the screen will give you nothing!
>
> To get around the problem, you must instruct the interpreter to scan
> multiple-line statements one at a time, not as a block. Here is how it's
> done. Note the exclamation marks!
>
> @echo off
> setlocal EnableDelayedExpansion
>
> for %%f in (*.*) do (
> set fn=%%f
> echo !fn!
> set fn2=%1%fn%
> echo !fn!
> )
> echo %fn%- Hide quoted text -


Thanks for the patience with this newbie. It was kinda surprising to
me. I wish MS would make it easier for us in their newer software
(Vista?). It's counter-intuitive to say the least, very likely to
trap up people coming over from other shell environments.

======================

Intuitive? What's intuitive about code like this:
for %%G in (%fn%) do set fz1=%%~zG
for %%H in (%fn2%) do set fz2=%%~zH
echo fz1=%fz1% fz2=%fz2%
 
Re: for loop variable insanity


> Thanks for the patience with this newbie. It was kinda surprising to
> me. I wish MS would make it easier for us in their newer software
> (Vista?). It's counter-intuitive to say the least, very likely to
> trap up people coming over from other shell environments.
>


I take it you mean unix/bash, in which case there is really no equivalent in
Windows. I think you'll find that most people resort to scripting languages
for tasks like this. VBScript, KiXStart, AutoIt, etc. To perform your task in
AutoIt is relatively simple, as it includes directory-list commands.

>
> Intuitive? What's intuitive about code like this:
> for %%G in (%fn%) do set fz1=%%~zG
> for %%H in (%fn2%) do set fz2=%%~zH
> echo fz1=%fz1% fz2=%fz2%
>


Might even be a prizewinner <g>

http://en.wikipedia.org/wiki/Obfuscated_C_Contest
 
Re: for loop variable insanity

On Sep 12, 4:47 pm, "Pegasus \(MVP\)" <I....@fly.com.oz> wrote:
> "emrefan" <dksle...@hotmail.com> wrote in message
>
> news:1f37e305-22fd-42a8-958d-fca3d4fa3eee@s28g2000prd.googlegroups.com...
> On Sep 12, 2:14 pm, "Pegasus \(MVP\)" <I....@fly.com.oz> wrote:
>
>
>
>
>
> > "emrefan" <dksle...@hotmail.com> wrote in message
> > > Now, every time I ran this batch file only things from the stupid to
> > > the absolute insane happened. The results did not make any sense at
> > > all. Sometimes the file sizes were insanely large, sometimes empty,
> > > other times the filenames fetched were those from the last run and
> > > were totally irrelevant to the recent invocation. I think the fact I
> > > am assigning the for loop variable to another variable is making XP go
> > > berserk because if I had the for loop modified to this below things
> > > would appear normal.

>
> > > for %%f in (*.*) do echo %%~zf

>
> > > But of course that's not gonna get my job done. :(

>
> > Ah, the old environmental variable trap. You need to be aware that the
> > code
> > interpreter will scan single statement of the form
> > for %%f in (*.*) do (
> > set fn=%%f
> > echo %fn%
> > set fn2=%1%fn%
> > echo %fn%
> > )
> > exactly once. The emphasis is on "single", because the two brackets cause
> > these five lines of code to be treated as one single line of code. At the
> > initial scan time, the variable "%fn%" is not defined, hence echoing it to
> > the screen will give you nothing!

>
> > To get around the problem, you must instruct the interpreter to scan
> > multiple-line statements one at a time, not as a block. Here is how it's
> > done. Note the exclamation marks!

>
> > @echo off
> > setlocal EnableDelayedExpansion

>
> > for %%f in (*.*) do (
> > set fn=%%f
> > echo !fn!
> > set fn2=%1%fn%
> > echo !fn!
> > )
> > echo %fn%- Hide quoted text -

>
> Thanks for the patience with this newbie. It was kinda surprising to
> me. I wish MS would make it easier for us in their newer software
> (Vista?).  It's counter-intuitive to say the least, very likely to
> trap up people coming over from other shell environments.
>
> ======================
>
> Intuitive? What's intuitive about code like this:
> for %%G in (%fn%) do set fz1=%%~zG
>    for %%H in (%fn2%) do set fz2=%%~zH
>    echo fz1=%fz1% fz2=%fz2%- Hide quoted text -
>


I admit it is far from intuitive. But I was forced to write it as such
because I think we cannot have the ~z expansion with non-loop non-
numeric variables? I cannot have, say, %~zSomeVarContainingMyFileName%
or can I?
 
Re: for loop variable insanity


"emrefan" <dksleung@hotmail.com> wrote in message
news:7fe8bb72-14ed-43b2-87b7-eeab07712522@v13g2000pro.googlegroups.com...
On Sep 12, 4:47 pm, "Pegasus \(MVP\)" <I....@fly.com.oz> wrote:
> "emrefan" <dksle...@hotmail.com> wrote in message
>
> news:1f37e305-22fd-42a8-958d-fca3d4fa3eee@s28g2000prd.googlegroups.com...
> On Sep 12, 2:14 pm, "Pegasus \(MVP\)" <I....@fly.com.oz> wrote:
>
>
>
>
>
> > "emrefan" <dksle...@hotmail.com> wrote in message
> > > Now, every time I ran this batch file only things from the stupid to
> > > the absolute insane happened. The results did not make any sense at
> > > all. Sometimes the file sizes were insanely large, sometimes empty,
> > > other times the filenames fetched were those from the last run and
> > > were totally irrelevant to the recent invocation. I think the fact I
> > > am assigning the for loop variable to another variable is making XP go
> > > berserk because if I had the for loop modified to this below things
> > > would appear normal.

>
> > > for %%f in (*.*) do echo %%~zf

>
> > > But of course that's not gonna get my job done. :(

>
> > Ah, the old environmental variable trap. You need to be aware that the
> > code
> > interpreter will scan single statement of the form
> > for %%f in (*.*) do (
> > set fn=%%f
> > echo %fn%
> > set fn2=%1%fn%
> > echo %fn%
> > )
> > exactly once. The emphasis is on "single", because the two brackets
> > cause
> > these five lines of code to be treated as one single line of code. At
> > the
> > initial scan time, the variable "%fn%" is not defined, hence echoing it
> > to
> > the screen will give you nothing!

>
> > To get around the problem, you must instruct the interpreter to scan
> > multiple-line statements one at a time, not as a block. Here is how it's
> > done. Note the exclamation marks!

>
> > @echo off
> > setlocal EnableDelayedExpansion

>
> > for %%f in (*.*) do (
> > set fn=%%f
> > echo !fn!
> > set fn2=%1%fn%
> > echo !fn!
> > )
> > echo %fn%- Hide quoted text -

>
> Thanks for the patience with this newbie. It was kinda surprising to
> me. I wish MS would make it easier for us in their newer software
> (Vista?). It's counter-intuitive to say the least, very likely to
> trap up people coming over from other shell environments.
>
> ======================
>
> Intuitive? What's intuitive about code like this:
> for %%G in (%fn%) do set fz1=%%~zG
> for %%H in (%fn2%) do set fz2=%%~zH
> echo fz1=%fz1% fz2=%fz2%- Hide quoted text -
>


I admit it is far from intuitive. But I was forced to write it as such
because I think we cannot have the ~z expansion with non-loop non-
numeric variables? I cannot have, say, %~zSomeVarContainingMyFileName%
or can I?

===============

Yes, you can but it gets even less intuitive. I suggest you start by
describing your requirement in functional terms.
 
Re: for loop variable insanity

On 9¤ë17¤é, ¤U¤È1®É18¤À, "Pegasus \(MVP\)" <I....@fly..com.oz> wrote:
> "emrefan" <dksle...@hotmail.com> wrote in message
>
> news:7fe8bb72-14ed-43b2-87b7-eeab07712522@v13g2000pro.googlegroups.com...
> On Sep 12, 4:47 pm, "Pegasus \(MVP\)" <I....@fly.com.oz> wrote:
>
>
>
>
>
> > "emrefan" <dksle...@hotmail.com> wrote in message

>
> >news:1f37e305-22fd-42a8-958d-fca3d4fa3eee@s28g2000prd.googlegroups.com....
> > On Sep 12, 2:14 pm, "Pegasus \(MVP\)" <I....@fly.com.oz> wrote:

>
> > > "emrefan" <dksle...@hotmail.com> wrote in message
> > > > Now, every time I ran this batch file only things from the stupid to
> > > > the absolute insane happened. The results did not make any sense at
> > > > all. Sometimes the file sizes were insanely large, sometimes empty,
> > > > other times the filenames fetched were those from the last run and
> > > > were totally irrelevant to the recent invocation. I think the fact I
> > > > am assigning the for loop variable to another variable is making XP go
> > > > berserk because if I had the for loop modified to this below things
> > > > would appear normal.

>
> > > > for %%f in (*.*) do echo %%~zf

>
> > > > But of course that's not gonna get my job done. :(

>
> > > Ah, the old environmental variable trap. You need to be aware that the
> > > code
> > > interpreter will scan single statement of the form
> > > for %%f in (*.*) do (
> > > set fn=%%f
> > > echo %fn%
> > > set fn2=%1%fn%
> > > echo %fn%
> > > )
> > > exactly once. The emphasis is on "single", because the two brackets
> > > cause
> > > these five lines of code to be treated as one single line of code. At
> > > the
> > > initial scan time, the variable "%fn%" is not defined, hence echoing it
> > > to
> > > the screen will give you nothing!

>
> > > To get around the problem, you must instruct the interpreter to scan
> > > multiple-line statements one at a time, not as a block. Here is how it's
> > > done. Note the exclamation marks!

>
> > > @echo off
> > > setlocal EnableDelayedExpansion

>
> > > for %%f in (*.*) do (
> > > set fn=%%f
> > > echo !fn!
> > > set fn2=%1%fn%
> > > echo !fn!
> > > )
> > > echo %fn%- Hide quoted text -

>
> > Thanks for the patience with this newbie. It was kinda surprising to
> > me. I wish MS would make it easier for us in their newer software
> > (Vista?). It's counter-intuitive to say the least, very likely to
> > trap up people coming over from other shell environments.

>
> > ======================

>
> > Intuitive? What's intuitive about code like this:
> > for %%G in (%fn%) do set fz1=%%~zG
> > for %%H in (%fn2%) do set fz2=%%~zH
> > echo fz1=%fz1% fz2=%fz2%- Hide quoted text -

>
> I admit it is far from intuitive. But I was forced to write it as such
> because I think we cannot have the ~z expansion with non-loop non-
> numeric variables? I cannot have, say, %~zSomeVarContainingMyFileName%
> or can I?
>
> ===============
>
> Yes, you can but it gets even less intuitive. I suggest you start by
> describing your requirement in functional terms.- ÁôÂóQ¤Þ¥Î¤å¦r -


By that yes you do mean I can write something like %~zSOME_VAR% and
get back the size of the file whose name is contained in variable
SOME_VAR? Well I just tested that and failed.

As for the functional spec, in my first post, I said "I wanted to
write a batch file for comparing files in the current
directory with those in another directory in terms of file size."
Does that qualify as a functional spec?
 
Re: for loop variable insanity


"emrefan" <dksleung@hotmail.com> wrote in message
news:9d0bb4da-531e-4b47-b5dd-82d3cb1f0534@l33g2000pri.googlegroups.com...
On 9¤ë17¤é, ¤U¤È1®É18¤À, "Pegasus \(MVP\)" <I....@fly.com.oz> wrote:
> "emrefan" <dksle...@hotmail.com> wrote in message
>
> news:7fe8bb72-14ed-43b2-87b7-eeab07712522@v13g2000pro.googlegroups.com...
> On Sep 12, 4:47 pm, "Pegasus \(MVP\)" <I....@fly.com.oz> wrote:
>
>
>
>
>
> > "emrefan" <dksle...@hotmail.com> wrote in message

>
> >news:1f37e305-22fd-42a8-958d-fca3d4fa3eee@s28g2000prd.googlegroups.com...
> > On Sep 12, 2:14 pm, "Pegasus \(MVP\)" <I....@fly.com.oz> wrote:

>
> > > "emrefan" <dksle...@hotmail.com> wrote in message
> > > > Now, every time I ran this batch file only things from the stupid to
> > > > the absolute insane happened. The results did not make any sense at
> > > > all. Sometimes the file sizes were insanely large, sometimes empty,
> > > > other times the filenames fetched were those from the last run and
> > > > were totally irrelevant to the recent invocation. I think the fact I
> > > > am assigning the for loop variable to another variable is making XP
> > > > go
> > > > berserk because if I had the for loop modified to this below things
> > > > would appear normal.

>
> > > > for %%f in (*.*) do echo %%~zf

>
> > > > But of course that's not gonna get my job done. :(

>
> > > Ah, the old environmental variable trap. You need to be aware that the
> > > code
> > > interpreter will scan single statement of the form
> > > for %%f in (*.*) do (
> > > set fn=%%f
> > > echo %fn%
> > > set fn2=%1%fn%
> > > echo %fn%
> > > )
> > > exactly once. The emphasis is on "single", because the two brackets
> > > cause
> > > these five lines of code to be treated as one single line of code. At
> > > the
> > > initial scan time, the variable "%fn%" is not defined, hence echoing
> > > it
> > > to
> > > the screen will give you nothing!

>
> > > To get around the problem, you must instruct the interpreter to scan
> > > multiple-line statements one at a time, not as a block. Here is how
> > > it's
> > > done. Note the exclamation marks!

>
> > > @echo off
> > > setlocal EnableDelayedExpansion

>
> > > for %%f in (*.*) do (
> > > set fn=%%f
> > > echo !fn!
> > > set fn2=%1%fn%
> > > echo !fn!
> > > )
> > > echo %fn%- Hide quoted text -

>
> > Thanks for the patience with this newbie. It was kinda surprising to
> > me. I wish MS would make it easier for us in their newer software
> > (Vista?). It's counter-intuitive to say the least, very likely to
> > trap up people coming over from other shell environments.

>
> > ======================

>
> > Intuitive? What's intuitive about code like this:
> > for %%G in (%fn%) do set fz1=%%~zG
> > for %%H in (%fn2%) do set fz2=%%~zH
> > echo fz1=%fz1% fz2=%fz2%- Hide quoted text -

>
> I admit it is far from intuitive. But I was forced to write it as such
> because I think we cannot have the ~z expansion with non-loop non-
> numeric variables? I cannot have, say, %~zSomeVarContainingMyFileName%
> or can I?
>
> ===============
>
> Yes, you can but it gets even less intuitive. I suggest you start by
> describing your requirement in functional terms.- ÁôÂóQ¤Þ¥Î¤å¦r -


By that yes you do mean I can write something like %~zSOME_VAR% and
get back the size of the file whose name is contained in variable
SOME_VAR? Well I just tested that and failed.

As for the functional spec, in my first post, I said "I wanted to
write a batch file for comparing files in the current
directory with those in another directory in terms of file size."
Does that qualify as a functional spec?

=====================

Yes, it does, and here is a solution that is almost intuitive.
@echo off
set source=d:\temp
set target=e:\Test Folder
for /F "delims=" %%a in ('dir /b "%source%\*.*"') do call :Sub %%a
goto :eof

:Sub
for %%b in ("%source%\%*") do set SSize=%%~zb
for %%b in ("%target%\%*") do set TSize=%%~zb
if %SSize%==%TSize% goto :eof
echo The size of "%1" in "%Source%" is not the same as in "%Target%".
 
Back
Top