Solved

BATCH FILE: FOR /R

Posted on 2010-08-26
63
720 Views
Last Modified: 2012-05-10
Hi there,

I must make the FOR /R command work inside the following batch file.

Please not that I need the FOR /R to be in the FOR /L as is.

@echo off
SETLOCAL enabledelayedexpansion
SET Dir1=C:\Batchfiles

FOR /L %%A IN (1,1,1) DO (
  FOR /R "!Dir%%A!" %%A IN (*.bat) do echo %%A
  )
PAUSE
EXIT


Thanks,
Rene
0
Comment
Question by:ReneGe
  • 31
  • 17
  • 14
63 Comments
 
LVL 68

Expert Comment

by:Qlemo
ID: 33537296
You've used %%A as var for both FORs. You need to use different loop vars:

@echo off
SETLOCAL enabledelayedexpansion
SET Dir1=C:\Batchfiles

FOR /L %%A IN (1,1,1) DO (
  FOR /R "!Dir%%A!" %%B IN (*.bat) do echo %%B
  )
PAUSE
EXIT /b

Further, don't use EXIT without /B in a batch file - it will close your cmd.exe, even if called manually.
0
 
LVL 68

Expert Comment

by:Qlemo
ID: 33537309
Any reason why you are not echoing the dir? Doesn't it matter where the batch files are located?
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33537330
Hey Q!

It still does not work.

Have any other ideas?

Cheers,
Rene
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33537336
?? I do echo the dir:  ...do echo %%B

What do you mean?
0
 
LVL 68

Expert Comment

by:Qlemo
ID: 33537352
"Still doesn't work" is kind of vague ...
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33537397
Sorry for that...

I get no output at all, but it does not close my cmd.exe

Just as a reference:
With the following, I get the expexted output.

@echo off

FOR /L %%A IN (1,1,1) DO (

  FOR /R "C:\Batchfiles" %%B IN (*.bat) do echo %%B

  )

PAUSE

EXIT /b

Open in new window

0
 
LVL 68

Expert Comment

by:Qlemo
ID: 33537420
Testing at the moment. FOR /R seems not to allow usuage of delayed expansion in the directory parameter.
0
 
LVL 68

Expert Comment

by:Qlemo
ID: 33537448
Any chance you change from
  set Dir1=C:\Batchfiles
  set Dir2=C:\OtherFiles
to
  set Dirs="C:\Batchfiles" "C:\Otherfiles"
?
0
 
LVL 68

Expert Comment

by:Qlemo
ID: 33537466
Background: Try the following in cmdline:

cmd /v:on
@set dir1=C:\Batchfiles
@for /R !dir1! %B in (*.bat) do @echo %B
@for /R %dir1% %B in (*.bat) do @echo %B
exit

Only the latter will succeed.
0
 
LVL 68

Accepted Solution

by:
Qlemo earned 250 total points
ID: 33537543
A workaround, maintaining your dir variables, is
@echo off



SETLOCAL enabledelayedexpansion

SET Dir1=Batchfiles



FOR /L %%A IN (1,1,1) DO call :search !Dir%%A!

pause

exit /b



:search

FOR /R "%1" %%B IN (*.bat) do echo %%B

EXIT /b

Open in new window

0
 
LVL 10

Author Comment

by:ReneGe
ID: 33537549
cmd /v:on
@set dir1=C:\Batchfiles
@for /R !dir1! %B in (*.bat) do @echo %B   =  NO OUTPUT
@for /R %dir1% %B in (*.bat) do @echo %B  =  EXPECTED OUTPUT
0
 
LVL 68

Expert Comment

by:Qlemo
ID: 33537642
As I wrote. No delayed expansion after /R ...
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33537660
Seems I'll have to use CALL here...

Thanks Q for all your help.

Cheers,
Rene
0
 
LVL 51

Expert Comment

by:Bill Prew
ID: 33537766
Sorry, been away for the day with real work :-).

You can avoid the call with this approach, for what it's worth...

@echo off
SETLOCAL enabledelayedexpansion
SET Dir1=C:\BatchFiles
FOR /L %%A IN (1,1,1) DO (
  FOR /F "tokens=*" %%B IN ('dir /s /b "!Dir%%A!\*.pdf"') do echo %%B
)
PAUSE
EXIT

~bp
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33537768
Quelmo,

Just to let you know that with your help, I corrected my script and it works like a charm.

Thanks a lot pal...

Cheers,
Rene

0
 
LVL 68

Expert Comment

by:Qlemo
ID: 33537779
BIll,
that's right, with exception of that it should search for .bat, not .pdf ;-)
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33537815
==> billprew
Than's what I used at first (...dir /s /b...), but it must pass through 150 000 files and it was just to long.

Thanks for contributing :-)

Cheers,
Rene
0
 
LVL 51

Expert Comment

by:Bill Prew
ID: 33537825
==> Q

Yes, had done that for some testing at my end to keep the hits low.

==> R

I wouldn't think there would be a huge performance difference, I'm going to run a few tests, but did you quantify the difference over the same set of files?  And the first run doesn't count since it will cache some stuff for the future runs.

~bp
0
 
LVL 51

Expert Comment

by:Bill Prew
ID: 33537907
Okay, I did a test with the attached code.  the DIR approach is actually faster than the FOR /R approach on my machine.

I did two runs, against different directories.  And each test did a loop of three iterations of timings.  Below is the results.  The 5 second run was the first time that directory tree was traversed, so either approach would have been slow that time, since none of the data was in memory.

[Thu 08/26/2010 19:37:09.13 c:\temp]dirtime
[1] FOR
140 milliseconds
[1] DIR
109 milliseconds
[2] FOR
140 milliseconds
[2] DIR
109 milliseconds

[Thu 08/26/2010 19:37:11.85 c:\temp]dirtime
[1] FOR
5.0 seconds
[1] DIR
109 milliseconds
[2] FOR
234 milliseconds
[2] DIR
109 milliseconds
[3] FOR
234 milliseconds
[3] DIR
156 milliseconds

~bp
@echo off
for /L %%A in (1,1,3) do (
  echo [%%A] FOR
  timer /nologo
  for /R "c:\_temp" %%B in ("*.bat") do rem
  timer /nologo /s
  echo [%%A] DIR
  timer /nologo
  for /R  %%B in ('dir /b /s "c:\_temp\*.bat"') do rem
  timer /nologo /s
)

Open in new window

0
 
LVL 10

Author Comment

by:ReneGe
ID: 33537924
==> bp

Yes I see a huge differance. However, since their may be a cash involved, I will rerun both and let you know.

==>Q
Extensions are not important here.  I just added it for better performance while testing. I use *.*

Cheers,
Rene
0
 
LVL 68

Expert Comment

by:Qlemo
ID: 33537938
Rene,
You should consider to request for reopening the question, if this discussion leads to something.
0
 
LVL 68

Expert Comment

by:Qlemo
ID: 33537943
BTW, the dir /s/b approach was what came first into my mind, but I wanted to stay as tight as possible on the original code.
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33537944
==> bp

I just want to let you know that I closed this thread before you started to be involved.

So please feel free to stop contributing since I will not be able to give further points.

Where did you get this timer?

Thanks,
Rene
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33537950
==> Q

How do I reopen the question?
0
 
LVL 51

Expert Comment

by:Bill Prew
ID: 33537973
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33537982
Thanks Q
Thanks Modalot
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33537993
I will now do the test between both options and come right back.
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33538036
Here are my results.

[1] FOR
1 minute, 41 seconds
[1] DIR
16 milliseconds
[2] FOR
5.8 seconds
[2] DIR
16 milliseconds

@echo off

FOR /L %%A in (1,1,2) do (

  echo [%%A] FOR

  timer /nologo

  for /R "S:" %%B in (*.*) do rem

  timer /nologo /s

  echo [%%A] DIR

  timer /nologo

  for /R  %%B in ('dir /b /s "S:"') do rem

  timer /nologo /s

)

Open in new window

0
 
LVL 51

Expert Comment

by:Bill Prew
ID: 33538061
Looks like DIR is the way to go ;-).

~bp
0
 
LVL 51

Expert Comment

by:Bill Prew
ID: 33538067
Actually, you need to change your script, not quite right.

~bp
@echo off
FOR /L %%A in (1,1,2) do (
  echo [%%A] FOR
  timer /nologo
  for /R "S:\" %%B in (*.*) do rem
  timer /nologo /s
  echo [%%A] DIR
  timer /nologo
  for /R  %%B in ('dir /b /s "S:\*.*"') do rem
  timer /nologo /s
)

Open in new window

0
 
LVL 10

Author Comment

by:ReneGe
ID: 33538130
HERE BETTER...

[1] FOR
5.7 seconds
[1] DIR
2.9 seconds
[2] FOR
5.9 seconds
[2] DIR
15.3 seconds

@echo off

FOR /L %%A in (1,1,2) do (

  echo [%%A] FOR

  timer /nologo

  for /R "S:" %%B in (*.*) do rem

  timer /nologo /s

  echo [%%A] DIR

  timer /nologo

  PUSHD s:\

  for /R  %%B in ('dir /b /s') do rem

  POPD

  timer /nologo /s

)

Open in new window

0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 51

Expert Comment

by:Bill Prew
ID: 33538165
Crud, I see I made a mistake earlier.  You want to do it this way:

@echo off
FOR /L %%A in (1,1,3) do (
  echo [%%A] FOR
  timer /nologo
  for /R "S:\" %%B in (*.*) do rem
  timer /nologo /s
  echo [%%A] DIR
  timer /nologo
  for /F "tokens=*" %%B in ('dir /b /s "s:\*.*"') do rem
  timer /nologo /s
)

~bp
0
 
LVL 51

Expert Comment

by:Bill Prew
ID: 33538191
So, now that I have the code correct (sorry guys), they seem to run in about the same time on my system.

~bp
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33538194
It does not seem to like ...('dir /b /s "s:\*.*"')
I had to add "PUSHD S:" before
0
 
LVL 51

Expert Comment

by:Bill Prew
ID: 33538205
It should work as I provided, what error did you get?

~bp
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33538212
It DIRs throuch the C drive
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33538213
It DIRs through the C drive
0
 
LVL 51

Expert Comment

by:Bill Prew
ID: 33538236
How do you know that, since it doesn't display any file info?

~bp
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33538261
I tested it with a smaller dir eching %%B , but I made a finger glitch.

You are right, your script works.

I will try it now...

I'll be back!
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33538297
After 4 minutes, I'm still at:

[1] FOR
5.7 seconds
[1] DIR

I'm still at work. I'll go home and continue from there.
@echo off

FOR /L %%A in (1,1,1) do (

  echo [%%A] FOR

  timer /nologo

  for /R "S:\" %%B in (*.*) do rem

  timer /nologo /s

  echo [%%A] DIR

  timer /nologo

  for /F "tokens=*" %%B in ('dir /b /s "S:\*.*"') do rem

  timer /nologo /s

)

Open in new window

0
 
LVL 10

Author Comment

by:ReneGe
ID: 33538566
[1] FOR
5.7 seconds
[1] DIR
28 minutes, 32 seconds
0
 
LVL 51

Expert Comment

by:Bill Prew
ID: 33538598
I assumed s: is a network drive?

~bp
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33538713
3 sata drives in RAID 0
0
 
LVL 51

Expert Comment

by:Bill Prew
ID: 33540831
So that's local storage.  Don't understand why your results could be so different than mine.  Can you post up the exact script you are using?

~bp
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33541039
I just changed the script in order to get a better idea.

Here are the results.

Also, when I look to the properties of the folder, I get 149957 files

Now, I have to figure out why the file quantites are so different.

But anyway, not ennuf to justify the time difference.

[1] FOR
Files:144374
2 minutes, 25 seconds
************************
[1] DIR
Files:157695
29 minutes, 42 seconds
@echo off



SETLOCAL enabledelayedexpansion



SET ForNUM=0

SET DirNUM=0



FOR /L %%A in (1,1,1) do (

  echo [%%A] FOR

  timer /nologo

  for /R "S:\" %%B in (*.*) do SET /a ForNUM=!ForNUM! + 1

  ECHO Files:!ForNUM!

  timer /nologo /s

  echo ************************

  echo [%%A] DIR

  timer /nologo

  for /F "tokens=*" %%B in ('dir /b /s "S:\*.*"') do SET /a DirNUM=!DirNUM! + 1

  ECHO Files:!DirNUM!

  timer /nologo /s

)

Open in new window

0
 
LVL 51

Expert Comment

by:Bill Prew
ID: 33541105
As far as the file counts, try adding /a-d to the DIR command to see if that gets closer.

~bp
0
 
LVL 68

Expert Comment

by:Qlemo
ID: 33541338
BTW, for incrementing it is better to use
    set /A ForNUM += 1
as it does not require variable expansion.
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33541507
Thanks Q & bp

I'll change it now and try again.

I'll be back...
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33541909
The discrepancy between DIR and number of files from Explorer properties is kind of resolved.

Anyway, it is now clear that FOR is much faster than DIR.

I am just concerned that, due to the difference between DIR and FOR in file qtee, if I use FOR /R, I might skip some important files, so this will also need to be resolved.  Have any ideas?


WITH DELAYED EXPANSION ON
[1] FOR
Files:144377
25.1 seconds
************************
[1] DIR
Files:149969
26 minutes, 46 seconds

Cheers,
Rene

@echo off



SETLOCAL enabledelayedexpansion



SET ForNUM=0

SET DirNUM=0

ECHO WITH DELAYED EXPANSION ON



FOR /L %%A in (1,1,1) do (

  echo [%%A] FOR

  timer /nologo

  for /R "S:\" %%B in (*.*) do SET /A ForNUM +=1

  ECHO Files:!ForNUM!

  timer /nologo /s

  echo ************************

  echo [%%A] DIR

  timer /nologo

  for /F "tokens=*" %%B in ('DIR /a-d /b /s "S:\*.*"') do SET /A DirNUM +=1

  ECHO Files:!DirNUM!

  timer /nologo /s

)

Open in new window

0
 
LVL 51

Assisted Solution

by:Bill Prew
Bill Prew earned 250 total points
ID: 33544785
Okay, it seems to be dramatically impacted by the number of files involved.  For whatever reason, the FOR approach clobbers the DIR approach when the number of files gets 'large'.  Here are the results of three tests I did against different drives on my system, the last of which was an external USB device.

~bp
Dir = [g:\], [*.*]
  LOOP = [1]
    FOR = Files:[124], Time:[78 milliseconds]
    DIR = Files:[124], Time:[62 milliseconds]
  LOOP = [2]
    FOR = Files:[124], Time:[46 milliseconds]
    DIR = Files:[124], Time:[78 milliseconds]
  LOOP = [3]
    FOR = Files:[124], Time:[78 milliseconds]
    DIR = Files:[124], Time:[62 milliseconds]

Dir = [c:\], [*.*]
  LOOP = [1]
    FOR = Files:[224248], Time:[1 minute, 57 seconds]
    DIR = Files:[230341], Time:[22 minutes, 46 seconds]
  LOOP = [2]
    FOR = Files:[224276], Time:[35.1 seconds]
    DIR = Files:[230370], Time:[22 minutes, 32 seconds]
  LOOP = [3]
    FOR = Files:[224300], Time:[37.1 seconds]
    DIR = Files:[230398], Time:[22 minutes, 7 seconds]

Dir = [e:\], [*.*]
  LOOP = [1]
    FOR = Files:[22877], Time:[36.4 seconds]
    DIR = Files:[27406], Time:[19.2 seconds]
  LOOP = [2]
    FOR = Files:[22877], Time:[1.6 seconds]
    DIR = Files:[27406], Time:[19.4 seconds]
  LOOP = [3]
    FOR = Files:[22877], Time:[1.5 seconds]
    DIR = Files:[27406], Time:[19.3 seconds]

Open in new window

0
 
LVL 10

Author Comment

by:ReneGe
ID: 33545496
So, assuming that your USB drive is the E: drive, is it fair for me to assume that something went wrong in the script? Unless your HDs are extremly slow.

Rene
0
 
LVL 51

Expert Comment

by:Bill Prew
ID: 33545664
Nothing went wrong, I have 10 times the number of files on the C: drive.

~bp
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33545864
lol

Your indicated file sizes all looks so much the same. I got caught in a visual paradigm and did not realized that there was an extra decimal.

I guess we concluded this thread. what do you think?

Cheers,
Rene
0
 
LVL 51

Expert Comment

by:Bill Prew
ID: 33545886
Yes, I suppose we've beat this to death.  I'm rather surprised at the terrible performance of DIR, but it is what it is I guess.

~bp
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33545941
Now we know...

It was nice working with you on this...

Have fun,
Rene
0
 
LVL 68

Expert Comment

by:Qlemo
ID: 33545979
But noone can explain that yet?! Sounds strange to me ... It should not be a big difference, if at all. The only explanation I have is that the dir output is collected as a whole first, then parsed thru the FOR (so a "big" temporary file needs to be created) , while the FOR /R is applied to folder after folder, giving the system some rest to settle down and balance the cache - maybe.
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33546058
==>Q

I have the same feeling.

The explanation of the FOR /R command as per: http://ss64.com/nt/for_r.html

This command walks down the folder tree starting at [drive:]path, and executes the DO statement against each matching file.

Have fun,
Rene
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33546169
==> Q
Do you also feel that we have concluded this thread?
0
 
LVL 68

Expert Comment

by:Qlemo
ID: 33546426
Yes, but I cannot recommend how you should close ... The discussion alone and in its whole is worth the points, though the initial answer is still correct.

Anyways, both issues with FOR /R are recorded for my (yet to create) part 2 of DOS anomalies. Thanks, Bill, for the thorough analysis of the timing - I guess we all have learned something ;-).

Thinking over that, we (Bill and I) should give YOU points for asking this interesting question :).
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33546469
Your help and friendship is ennuf.

Thanks for the thought though.

Again, it was nice working with you guys!

Thanks a lot for all your help.

Cheers,
Rene
0
 
LVL 51

Expert Comment

by:Bill Prew
ID: 33546861
Agree, fun and interesting thread, glad to have been a part of it.

(and I still may poke more at this if time allows at some point down the road...)

~bp
0
 
LVL 10

Author Comment

by:ReneGe
ID: 33563266
Guys, something is wrong, so I was unable to but my new thread in the Windows Batch zone.

I thought you may what to have a look at this one.

http://www.experts-exchange.com/OS/Microsoft_Operating_Systems/MS_DOS/Q_26439921.html

Thanks for your help & cheers,
Rene
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
stringclean challenge 26 56
delphi parse string to params 3 82
base64 decode encode 12 97
how to use wail2ban ?? 13 36
This article is meant to give a basic understanding of how to use R Sweave as a way to merge LaTeX and R code seamlessly into one presentable document.
Although it can be difficult to imagine, someday your child will have a career of his or her own. He or she will likely start a family, buy a home and start having their own children. So, while being a kid is still extremely important, it’s also …
An introduction to basic programming syntax in Java by creating a simple program. Viewers can follow the tutorial as they create their first class in Java. Definitions and explanations about each element are given to help prepare viewers for future …
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now