批处理文件:用于recurses目录的循环,具有目录通配符和文件通配符

时间:2017-11-20 10:41:28

标签: batch-file for-loop

简而言之:如何为匹配proto/acme*/**/*.proto的每个文件运行命令,其中" **"是指递归子目录深度?

更长的细节:

我有一个像这样的目录结构:

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

我想要一个运行以下内容的批处理文件(但即使当前文件列表发生了变化,也能正常工作):

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!

我目前有两个难题(用%替换每个%%批处理文件而不是命令行):

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

我想要的是一个迭代所有*.proto文件的for循环,但仅限于proto\acme_*。执行此操作的单个for循环将是理想的,但是也可以使用嵌套for循环(在外循环中使用proto\acme*并在内部使用**\*.proto),但我无法弄清楚如何让它工作。

另一种想法是递归查找所有*.proto,然后在其中有一个if语句,检查文件是否以proto\acme_开头。错误匹配的数量足够小,以至于这不会成为速度问题。一个复杂的问题是for /r似乎返回绝对路径,但是在文件名中的任何位置匹配proto\acme_的解决方案都没问题。

1 个答案:

答案 0 :(得分:1)

我从an answer找到了类似(但不完全相同)问题的答案。为了避免在内部循环的条件下使用外部循环中的变量的问题,您可以在循环中更改目录:

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