svandragt
svandragt

Reputation: 1720

run command in each subfolder

What is the easiest way to run a command in each subfolder of a path? In this case I have to run svn cleanup for every directory in my repository.

Upvotes: 4

Views: 7029

Answers (4)

aschipfl
aschipfl

Reputation: 34979

As already stated in another answer, the for /R command helps:

for /D /R %I in ("*") do @echo "%~I"

To explicitly specify the root directory do this:

for /D /R "D:\Root" %I in ("*") do @echo "%~I"

Quite the same can be achieved by the dir command together with for /F:

for /F "delims=" %I in ('dir /S /B /A:D "D:\Root\*"') do @echo "%~I"

This command line, as well as the aforementioned ones, walk through the directory tree from top to bottom. To reverse that just incorporate the sort command:

for /F "delims=" %I in ('dir /S /B /A:D "D:\Root\*" ^| sort /R') do @echo "%~I"

All of the above excluds the root directory from being returned. To include it use the following code:

for /F "delims=" %J in ('^(for /R "D:\Root" %I in ^(.^) do @echo "%~fI"^)') do @echo "%~J"

To reverse the order from bottom to top again, use this one:

for /F "delims=" %J in ('^(for /R "D:\Root" %I in ^(.^) do @echo "%~fI"^^^& rem/^) ^| sort /R') do @echo "%~J"

Upvotes: 1

Joey
Joey

Reputation: 354794

I have found that in such cases it is much easier to just delete the working copy and re-checkout. If you have local changes, then copy the changed files elsewhere first.

But Can's answer might work in your case, unless SVN has greater problems. Though you probably have to run it several times since it would begin at the root folder which would still have problems, then. You'd need some kind of post-order traversal in that case which can't be done with for /r but which can ensure that you would start with the lowest directories in the hierarchy to clean up.

You'd also need to exclude SVN's statekeeping directories .svn:

for /r /d %i in (*) do if NOT %i==.svn svn cleanup %i

As for the post-order traversal, you can build a little batch:

@echo off
call :recurse "."
goto :eof

:recurse
pushd %1
if not %~1==.svn (
    for /d %%i in (*) do call :recurse "%%i"
    echo svn cleanup %~1
)
popd
goto :eof

On the following tree:

a
├───.svn
├───a1
│   └───.svn
└───a2
    └───.svn
b
├───.svn
├───b1
│   ├───.svn
│   ├───b11
│   │   └───.svn
│   └───b12
│       └───.svn
└───b2

This yields the following output:

svn cleanup "a1"
svn cleanup "a2"
svn cleanup "a"
svn cleanup "b11"
svn cleanup "b12"
svn cleanup "b1"
svn cleanup "b2"
svn cleanup "b"
svn cleanup "."

which, as you can see, makes sure that the lowest directories are processed first and the .svn directories are skipped. Remove the echo if you want to use it. This could resolve your problem. Maybe.

Upvotes: 4

user111095
user111095

Reputation:

for command is what you are looking for. In order to read about the exact syntax type for /?

For example, in order to print the names of all sub directories in the current directory. You can use the command:

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

The echo %i part is the part you must change to suit your case.

Upvotes: 7

Greg Hewgill
Greg Hewgill

Reputation: 994531

svn cleanup automatically recurses into subdirectories. I'm not sure why you would need to recurse manually for that particular command.

Upvotes: 1

Related Questions