Welcome to MSDN Blogs Sign in | Join | Help

Performing an operation in each subdirectory of a directory tree from batch

To execute a command in each subdirectory of a directory tree from a batch file, you can adapt the following:

for /f "delims=" %%i in ('dir /ad/s/b') do echo %%i

(If you want to play with this command from the command prompt, then undouble the percent signs.)

The /F option enables various special behaviors of the FOR command. The most important change is that a string in single-quotation marks causes the contents to be interpreted as a command whose output is to be parsed. (This behavior changes if you use the usebackq option, but I'm not using that here.) Therefore, the FOR command will run the dir /ad/s/b command and parse the output. The dir /ad/s/b command performs a recursive listing of only directories, printing just the names of the directories found.

The option we provide, delims= changes the default delimiter from a space to nothing. This means that the entire line is to be read into the %i variable. (Normally, only the first word is assigned to %i.) Therefore, the FOR loop executes once for each subdirectory, with the %i variable set to the subdirectory name.

The command request to be performed for each line is simply echoing the directory name. In real life, you would probably put something more interesting here. For example, to dump the security descriptor of each directory (which was the original problem that inspired this entry), you can type this on the command line:

for /f "delims=" %i in ('dir /ad/s/b') do cacls "%i" >>"%TEMP%\cacls.log"

Nitpicker's corner

I doubt anybody actually enjoys working with batch files, but that doesn't mean tips on using it more effectively aren't valid.

Published Friday, May 11, 2007 7:00 AM by oldnewthing
Filed under:

Comments

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 10:16 AM by Sohail

Batch files! NOOOOOOOOOOOOOOOOOOOoooooooooooooooooo..........

splat.

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 10:42 AM by Maxim

Alternatively:

for /r /d %%i in (*) do echo %%i

[Nice, but there's more to the "dir" trick than meets the eye. I'll come back to this. -Raymond]

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 11:19 AM by Jules

Or the other alternative (using cygwin)

find -type d -exec echo '{}' ';'

I do think the cygwin way of doing this kind of thing is substantially friendlier...

[Woo-hoo, now I have two problems. -Raymond]

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 11:32 AM by Dave

I prefer to use Windows Script Host for these kind tricks. The clumsiness of FileSystemObject can be hidden with some functions and you have all of Javascript (or VBScript) at your disposal for string operations. All the infrastructure is already down on the drive, at least since Windows 95.

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 12:08 PM by Adam

[Woo-hoo, now I have two problems. -Raymond]

Yes, but if you solve one of them *once*, it makes *all your other* problems easier to solve from then on. If you'd installed cygwin/perl/monad/whatever last March when it was originally suggested, you'd have *already* solved that problem, and would be able to solve this one more easily.

You make it sound like you have to re-install perl every time you want to write a perl script.

"Give me six hours to chop down a tree and I will spend the first four sharpening the axe."

-- Abraham Lincoln

Using batch files to accomplish all your automation goals is like trying to cut down all your trees with a rusty axe. If you could just take a day to leave the forest, find civilisation, and buy a damn chainsaw, you'll make the time up later. Honest.

"No, no, I can't take the time out to go and find proper tools - I'm too busy doing it slowly!"

[You have to install it on every computer that will run your script, which in a corporate setting can be hundreds or thousands. At some point, the trade-off will be worth it, and you can ignore all my batch file tips. Until then, the tips are there. -Raymond]

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 12:19 PM by Paul

"You make it sound like you have to re-install perl every time you want to write a perl script." - Adam

You are assuming you got the go ahead to install <whatever your technology of choice is by whatever vendor of choice> in the first place - as Raymond points out in the linked article this is not always trivial or even possible.

If you can dump the permissions of a file system tree on a production server to a file without installing and other software (which could introduce new security issues, training requirements etc.) then surely one line typed in at a cmd.exe prompt is a winner. After all this was only a 'tip' and not an attempt to promote using batch files in any way.

[I can imagine the support call now. "Hi, is there a quick way to dump the ACLs on all the directories on our server into a file?" "Why yes there is. First, install cygwin." *Click*. -Raymond]

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 12:20 PM by J

"You make it sound like you have to re-install perl every time you want to write a perl script."

And what if you do?  For instance, you're trying to debug a problem on a customer's PC that you've never seen before.

"Umm, do you mind if I install perl, Visual Studio, and Photoshop first before I can start debugging this issue?"

You know, you can use your head and figure out whether it really does cause you two problems instead of taking Raymond's word as gospel instead of advice.  If it turns out it doesn't cause you two problems, then good for you!  You deserve a treat for figuring that out yourself.

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 12:21 PM by El Guapo

This is a microsoft blog right? You never tried powershell I guess? Maybe you have heard of it. Its something your company makes.

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 12:24 PM by josh

Might as well mention "for /r /d %I in (.) do @echo %I" as well, which seems to be the method that whoever wrote the help text for the for command recommends.  You get names that end in \., but it lists directories that (*) misses.

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 12:28 PM by Aaron

Quoting Abraham Lincoln for a discussion on corporate IT - brilliant.  Totally misunderstanding the quote and using it in absolutely the wrong context - priceless.

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 12:29 PM by Peter Ritchie

Outstanding the nitpickability of these folks.  Raymond even added "I doubt anybody actually enjoys working with batch files...", meaning for those of use who *HAVE* to use batch files and cannot use anything else (locked-down PC, corporate standards, least common-denominator, etc. etc. etc.) then, as Raymond says, "doesn't mean tips on using it more effectively aren't valid."

Sheesh.

Looks like Raymond needs a nitpicker's prelude to explain why he's talking about what he's talking about.

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 12:30 PM by bionicbee

Is there any good documentation on the syntax for batch files? We have some homegrown scripts to do various things but some things are extremely hard to figure out, like how to deal with parentheses in strings, which comes up when trying to parse a PATH envvar on x64 systems for example.

It's humiliating (but mostly frustrating) for an expert C++ programmer to spend three hours figuring out how to append a string to another... in the end I wrote a .net app in five minutes to solve the problem.

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 12:35 PM by Dave

"This is a microsoft blog right? You never tried powershell I guess?"

I am pretty sure Raymond was looking to work with the tools already available on the island. That's why I mentioned WSH as an alternative as well. If you're going to download and MSH, Perl, Python, whatever on 100 or 1000 computers to solve a simple admin problem then you are wasting time.

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 12:54 PM by mikeb

>> Is there any good documentation on the syntax for batch files?

Not really - there's 3 decent resources for Windows batch scripting that I know of:

1) cmd.exe's help facility (just type "help" or use the /? option for the command you want specific help on).

2) Tim Hill's book "Windows NT Shell Scripting" (http://www.amazon.com/dp/1578700477/)

3) Google

Unfortunately, cmd's batch syntax seems to have grown more or less organically, rather than been designed.  In particular the behavior for quoting characters and strings can be strange an unintuitive. So it can be quite painful to do much in the way of string manipulation.

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 12:55 PM by Mihai

Thanks for the tip, batch files are still good for a lot of things.

And when I need something more powerful, I have discovered a cool tool a while ago: KiStart http://www.kixtart.org/index.asp

Needs no installation (just drop 2 files with your script), and has a scripting language, can do ole automation, registry access, reading files, etc, and.

Sure, Perl, Awk, PowerShell, have their place and I use them. But knowing more tools allows you to choose the best for the job.

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 12:57 PM by RyanBemrose

@bionicbee: If all you want is documentation on commands, search for "command processor" in MSDN, or try "help whatever" at the command-line.

For more in-depth stuff, I highly recommend "Windows NT Shell Scripting" by Tim Hill.

http://www.amazon.com/Windows-Shell-Scripting-Timothy-Hill/dp/1578700477

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 12:57 PM by mikeb

>> You never tried powershell I guess? Maybe you have heard of it.

What's your point?  The fact that PowerShell exists makes old-fashioned batch files useless now?  All those little .cmd files in my \util directory have not seemed to notice.

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 1:02 PM by Fox Cutter

This is a usefull tip. I'm always surprised by how much you can do with the command language in Windows. There's quite a lot you can do using it without having to go into other applications.

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 1:42 PM by cmov

"[You have to install it on every computer that will run your script, which in a corporate setting can be hundreds or thousands. At some point, the trade-off will be worth it, and you can ignore all my batch file tips. Until then, the tips are there. -Raymond]"

But for your tips, I would need to install Windows.

Eek.

[If your machines aren't already running Windows, then yes, you would have to install Windows, too, and that would be quite a burden. I guess I have to add a new sentence to the nitpicker's corner now. -Raymond]

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 1:56 PM by Stuart Langridge

I do this kind of thing all the time. There's a certain punk cachet in doing cool things with batch that I enjoy. Sort of a question (although this should maybe have gone to the suggestion box): do you know why usebackq isn't the default? It seems slightly odd to me that since a "syntax" for "run a command and get its output" already existed (backticks) that cmd.exe implemented a different one (single quotes) and then put in the backticks as a config option. This might not be a Raymond question at all; I don't know whether the command shell comes under the aegis of the shell team, ironically enough!

[You have your history backwards. -Raymond]

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 1:59 PM by KJK::Hyperion

Ha! I used "tokens=*" instead of "delims=". And I use uppercase letters for the variable name, to make tilde expansions non-ambiguous. And you should prefix the "do" command with an @, or the command will be echoed. In other words, I'd use:

for /f "tokens=*" %%I in ('dir /ad/s/b') do @echo %%I

Also, how to perform an infinite loop: for /l %I in (1,0,1) do ...

Finally a little warning: you can make a pipeline of "for" loops (and, indeed, any built-in command), but be aware that, if there are more than two in the same pipeline, each will be run in a subprocess. The /V and /E options won't be passed onto the cmd.exe subprocess, I guess as a bug, and this might screw with !VARIABLE! expansion; in that case, you can sacrifice syntactic sugar by replacing the offending "for" loop with an explicit cmd /e:on /v:on /c "for ..."

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 2:01 PM by KJK::Hyperion

Stuart: thank GOD it isn't the default. It is a PAIN to type backquotes on certain keyboard layouts. Also I think single quotes came first and the alternate syntax was added later

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 2:04 PM by Stuart Langridge

Raymond: ah, OK, if I've got it backwards then I was wrong. Not sure what I've got backwards, mind :)

KJK::Hyperion: backticks are awkward to type? I clearly don't have as much experience of alternate keyboard layouts as I need, then!

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 2:12 PM by KJK::Hyperion

Stuart: Alt-096 on an Italian layout...

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 2:24 PM by coldacid

>Or the other alternative (using cygwin)

>

>find -type d -exec echo '{}' ';'

>

>I do think the cygwin way of doing this kind of

>thing is substantially friendlier...

I dunno... I'm a big fan of Cygwin myself, and I think that the way Raymond showed was far more readable.

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 2:25 PM by Mike C

Back in the days of DOS, I used a little utility called "Sweep" (http://short.stop.home.att.net/freesoft/batch2.htm#sweep) that did the same thing.

For example, "sweep del *.bak" would delete *.bak files from the current directory and all subdirectories under it.

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 2:30 PM by Maurits

> I doubt anybody actually enjoys working with batch files

/me sheepishly raises hand...

http://channel9.msdn.com/ShowPost.aspx?PostID=51329

http://channel9.msdn.com/ShowPost.aspx?PostID=189460

My particular favorite has to be xargs.bat, which allows the charmingly anaOStic

dir /b /a:-d *.cpp | xargs start

or

dir /b /a:-d *.cpp | xargs /addquotes start ""

(to placate start's weird argument syntax)

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 2:36 PM by Maurits

> You have to install it on every computer that will run your script, which in a corporate setting can be hundreds or thousands.

To be fair, in a corporate setting, installing Monad on hundreds or even thousands of computers is only about ten times as difficult as setting it up on one computer.

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 5:05 PM by Nick

I realize it's not exactly the point of this post, but for anyone who is interested, you might check out the free AutoIt (http://www.autoitscript.com/autoit3/). It has an incredibly full-featured API that lets you do nearly anything you'd want to on Windows. The syntax is a lot like Visual Basic, and you can compile the scripts into a standalone executable, so no need to install libraries, etc.

In any case, it has been very helpful for me in the past.

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 5:59 PM by AltMihai

Also, http://www.robvanderwoude.com/batchfiles.html is an invaluable resource for those who would invest some time in learning the Windows command line.

# re: Performing an operation in each subdirectory of a directory tree from batch

Friday, May 11, 2007 10:28 PM by telcor

>> You have to install it on every computer that will run your script, which in a corporate setting can be hundreds or thousands.

>To be fair, in a corporate setting, installing Monad on hundreds or even thousands of computers is only about ten times as difficult as setting it up on one computer.

Which supposes one already went through the bureaucracy to gain approval for installing software domain-wide

# re: Performing an operation in each subdirectory of a directory tree from batch

Saturday, May 12, 2007 12:36 AM by Richard

Adam, I won't go over how wrong your post as a whole is, but the quote you use stands out. I believe the meaning is that if you give people too much time for a task they'll waste time on things that don't actually help with the task.

If you have someone who has unlimited free time because they have no job and don't have to pay rent or buy food an acceptable solution might be to create a new programming language, build a community, and have the community come up with tools to solve their problem. People who have limited time have to devote all of it to actually solving the problem, not configuring new platforms.

# re: Performing an operation in each subdirectory of a directory tree from batch

Saturday, May 12, 2007 1:41 AM by Amit Schreiber

Steve Miller (creator of Dependency Walker) has a DOS toolbox application collection. One of these applications is global.exe, which let's you run a command for each subdirectory with some additional options. See his applications page for more details:

http://www.stevemiller.net/apps/

# re: Performing an operation in each subdirectory of a directory tree from batch

Saturday, May 12, 2007 4:40 AM by Sven Groot

Ah, batch files. I can never quite decide whether to feel nostalgic about them or just install PowerShell and say "good riddance". :P After spending a brief time (like, 30 minutes) with Exchange 2007 and PowerShell, the latter is more likely. :)

They are a good solution sometimes when you can't go off installing new stuff, but WScript also fits that description and is a lot more flexible. Bottom line, unless what I need to do really is nothing more than a simple sequence of commands, I tend to not use batch files.

Anti-nitpickers corner: this isn't to say the tips aren't useful and/or you should stop giving them.

# re: Performing an operation in each subdirectory of a directory tree from batch

Saturday, May 12, 2007 9:49 AM by Dewi Morgan

I love tips like this - I still have "which.bat" from one of the earlier tips posts, where people argued over which was the most elegant solution.

I admit I don't yet see the appeal of the

"for /r /d %I in (.) do @echo %I"

over

for /f "delims=" %%i in ('dir /ad/s/b') do echo %%i

...but that just makes me look forward more to the "I'll come back to this." post.

I notice very few people saying in the C posts "OMGWTFBBQ use Perl/Python/Java/Bash!" - why should this post be different? It's a post about cmd commands, it's blatantly obvious that there are alternatives out there, but that's no more the point than in the C language posts.

# re: Performing an operation in each subdirectory of a directory tree from batch

Saturday, May 12, 2007 6:13 PM by cmov

"[If your machines aren't already running Windows, then yes, you would have to install Windows, too, and that would be quite a burden. I guess I have to add a new sentence to the nitpicker's corner now. -Raymond]"

No, it's allright -_-' I was just kinda silly :p

# re: Performing an operation in each subdirectory of a directory tree from batch

Monday, May 14, 2007 1:07 AM by Anon

One trick I liked in Dos batch files is that you can have functions, you just need to simulate them with recursion, e.g.

if "%1"=="/foo" goto foo

if "%1"=="/bar" goto bar

@rem call function foo

call %0 /foo fooargs

@rem call function bar

call %0 /bar barargs

goto exit

:foo

@echo foo - args %2

goto exit

:bar

@echo bar - args %2

goto exit

:exit

The idea of a language which forces you to do this is oddly charming.

Though it turns out that in Windows, you can actually do this

@rem call function foo

call :foo fooargs

@rem call function bar

call :bar barargs

goto :EOF

:foo

@echo foo - args %2

goto :EOF

:bar

@echo bar - args %2

goto :EOF

Call now allows you to call labels as :label, and :EOF is a built in end of file label. Now that's progress ;-)

# re: Performing an operation in each subdirectory of a directory tree from batch

Monday, May 14, 2007 7:25 AM by Hayden

CMD.EXE's "help" command is a riot. Somebody has carefully (and reasonably completely) documented all of the cute and fun bits of the script language. It just most people don't know it's there ("help" on DOS5/6 wasn't wildly useful) and some of the more magically useful bits aren't where you might expect (PUSHD creating temporary drive mappings for UNC paths, for example).

# re: Performing an operation in each subdirectory of a directory tree from batch

Monday, May 14, 2007 8:46 AM by 640k

Raymond is rejecting cygwin not on technical basis. It's because his employer doesn't want him to appreciate other vendors applications.

[You may notice that I don't appreciate Microsoft applications either. I'm an equal-opportunity shunner. -Raymond]

# re: Performing an operation in each subdirectory of a directory tree from batch

Monday, May 14, 2007 11:51 AM by David Walker

I think Raymond wasn't "rejecting" CYGWIN, but if you read the linked article "now you have two problems" href=http://blogs.msdn.com/oldnewthing/archive/2006/03/22/558007.aspx all will be clear.

I hope the link works.

# re: Performing an operation in each subdirectory of a directory tree from batch

Monday, May 14, 2007 4:07 PM by Legolas

Hey thanks for this. I don't think I realized that you could specify no delims at all by using that option, when I wrote my last batch file. Time to go back and see if this simplifies things, it might well.

# re: Performing an operation in each subdirectory of a directory tree from batch

Tuesday, May 15, 2007 2:13 PM by Cooney

> Which supposes one already went through the bureaucracy to gain approval for installing software domain-wide

Not all corporate structures are completely hidebound. Installing something like perl shouldn't be all that hard, given its long history and the rather minimal security risks of having it there when you aren't using it.

# re: Performing an operation in each subdirectory of a directory tree from batch

Tuesday, May 15, 2007 5:36 PM by arnshea

Thanks for the tip!  Another one I've found useful is enabling delayed environment variable expansions (cmd /V:on).  That plus xcopy /D makes selectively deploying directory contents across a network onto an XPe target a cinch.

For nostalgia they're stored in c:\bin.  The XP command shell may not be bash but it's got quite a few hidden gems for the "not quite worth a program" level of automation.

# re: Performing an operation in each subdirectory of a directory tree from batch

Thursday, May 17, 2007 4:09 AM by Ema

Ooc, I really like Raymond's intellectual honesty...if every guy at his workplace were like him there where no FUD against other OSes and Windows would be a better product.

End of Ooc,

Cheers,

Ema! ;-)

# Office Access

Wednesday, May 23, 2007 9:14 PM by Jim Vaglia

I didn't receive Access with my copy of Office for XP so why did I receive a Microsoft Access security update? I removed Windows medea 6 security update so shouldn't streams play just fine in other media players?

[Did you try using the for command? -Raymond]

# Synesthesia &raquo; Links Roundup for 2007-05-14

Friday, August 10, 2007 8:04 AM by Synesthesia » Links Roundup for 2007-05-14
New Comments to this post are disabled
 
Page view tracker