Arthur Tacca
Arthur Tacca

Reputation: 9989

Batch file: For loop that recurses directory, has directory wildcard, and file wildcard

In short: how do I run a command for each file matching proto/acme*/**/*.proto, where "**" means recursive subdirectory depth?

Longer details:

I have a directory structure like this:

proto\
    acme_bar\
        l.proto
    acme_foo\
        abc\
            a.proto
            b.proto
        xyz\
            x.proto
    rand_rar\
        q.proto

I would like a batch file that runs the following (but works even if the current list of files changes, obviously):

protoc proto\acme_bar\l.proto
protoc proto\acme_foo\abc\a.proto
protoc proto\acme_foo\abc\b.proto
protoc proto\acme_foo\xyz\x.proto
rem NOT protoc proto\rand_rar\q.proto!

I currently have two pieces of the puzzle (replace each % with %% for a batch file rather than on the command line):

rem returns proto\acme_bar and proto\acme_foo
for /d %d in (proto\acme*) do echo %d
rem returns *.proto, recursing through all directories
for /r %p proto in (*.proto) do echo %p

What I want is a for loop that iterates over all *.proto files, but only in proto\acme_*. A single for loop that does this would be ideal, but alternatively a nested for loop would do (with proto\acme* in the outer loop and **\*.proto on the inside), but I can't figure out how to get that to work.

An alternative idea would be to just recursively find all *.proto and then have an if statement inside that checks whether the file starts with proto\acme_. The number of false matches would be small enough that this wouldn't be a problem speed wise. A complication is that for /r seems to return absolute paths, but a solution that matches proto\acme_ anywhere in the file name would be fine.

Upvotes: 1

Views: 86

Answers (1)

Arthur Tacca
Arthur Tacca

Reputation: 9989

I found the answer from an answer to a similar (but not exactly the same) question. To avoid the problem of using the variable from the outer loop in the conditional of the inner loop, you change directory in the loop:

SETLOCAL enableextensions disabledelayedexpansion
FOR /D %%D in (proto\acme_*) DO (
    PUSHD "%%D" && (
        FOR /r %%P in (*.proto) DO (
            protoc %%P
        )
        POPD
    )
)
ENDLOCAL

Upvotes: 1

Related Questions