第一个代码
FOR /D %%d IN ("D:\Folder*") DO (
FOR /R "%%d\logs" %%i IN (*) do echo %%i
)
失败,因为您不能在 for /r 的文件夹中使用 for 可替换参数。在for 解析器的工作方式中,用作/R 中使用的起始文件夹的值必须在for /d 开始执行之前可用。
第二个代码
FOR /D %%d IN ("D:\Folder*") DO (
SET fld=%%d
FOR /R "%fld%\logs" %%i IN (*) do echo %%i
)
失败,因为%fld% 不会像你想象的那样被解析。完整的for /d %%d 仅被解析为一个命令,并且该命令中的所有%var% 引用都被删除,在开始执行之前被存储在变量中的值替换。您不能更改变量的值并在同一命令中检索更改后的值,因为在执行时命令中不包含任何变量扩展,只有在解析命令时变量具有的值。
这通常是通过启用延迟扩展来处理的,因此您可以在需要的地方将 %var% 更改为 !var! 以向解析器指示变量扩展(值检索)应该延迟到执行命令为止。所以你可以写类似
setlocal enabledelayedexpansion
FOR /D %%d IN ("D:\Folder*") DO (
SET "fld=%%d"
FOR /R "!fld!\logs" %%i IN (*) do echo %%i
)
但是由于第一个代码中指出的相同原因,这也不起作用。解析时需要在/R 中使用的值。
那么,如何解决这个问题呢?
您可以通过首先将当前活动目录更改为for /D %%i正在迭代的文件夹来避免在/R中指示文件夹
for /d %%d in ("d:\Folder*") do (
pushd "%%~fd\logs" && (
for /r %%i in (*) do echo %%i
popd
)
)
或者你可以将内部循环放在一个单独的子程序中
for /d %%d in ("d:\Folder*") do call :process "%%d"
goto :eof
:process folderPath
for /r "%~1\logs" %%i in (*) do echo %%i
goto :eof
或者您可以将内部递归for 替换为for /f 处理递归dir
for /d %%d in ("d:\Folder*") do (
for /f "delims=" %%i in ('dir "%%~fd\logs" /a-d /b /s`) do echo %%i
)