Jump to content

for loop variable insanity


Recommended Posts

Posted

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. :(

  • Replies 8
  • Created
  • Last Reply
Guest Pegasus \(MVP\)
Posted

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%

Posted

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.

Guest Pegasus \(MVP\)
Posted

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%

Posted

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

Posted

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?

Guest Pegasus \(MVP\)
Posted

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.

Posted

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?

Guest Pegasus \(MVP\)
Posted

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%".


×
×
  • Create New...