Guest emrefan Posted September 12, 2008 Posted September 12, 2008 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. :(
Guest Pegasus \(MVP\) Posted September 12, 2008 Posted September 12, 2008 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%
Guest emrefan Posted September 12, 2008 Posted September 12, 2008 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 September 12, 2008 Posted September 12, 2008 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%
Guest Anteaus Posted September 12, 2008 Posted September 12, 2008 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
Guest emrefan Posted September 17, 2008 Posted September 17, 2008 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 September 17, 2008 Posted September 17, 2008 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.
Guest emrefan Posted September 22, 2008 Posted September 22, 2008 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 September 22, 2008 Posted September 22, 2008 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%".
Recommended Posts