This should be simple but is not working correctly.
FOR /D %%d IN ("D:\Folder*") DO (
FOR /R "%%d\logs" %%i IN (*) do echo %%i
)
pause
I have also tried:
FOR /D %%d IN ("D:\Folder*") DO (
SET fld=%%d
FOR /R "%fld%\logs" %%i IN (*) do echo %%i
)
pause
I feel that am missing something pretty basic.
Thanks!
First code
FOR /D %%d IN ("D:\Folder*") DO (
FOR /R "%%d\logs" %%i IN (*) do echo %%i
)
fails because you can not use a for
replaceable parameter in the folder of a for /r
. In the way the for
parser works, the value to use as the starting folder used in the /R
must be available before the for /d
starts to execute.
Second code
FOR /D %%d IN ("D:\Folder*") DO (
SET fld=%%d
FOR /R "%fld%\logs" %%i IN (*) do echo %%i
)
fails because %fld%
will not be parsed as you think. The full for /d %%d
is parsed as only one command and all the %var%
references inside this command are removed, being replaced with the value stored in the variables before starting to execute. You can not change a variable's value and retrieve the changed value inside the same command because while executing there is not any variable expansion included in the command, only the values the variables had when the command was parsed.
This is usually handled enabling delayed expansion so you can change where needed %var%
into !var!
to indicate to the parser that the variable expansion (value retrieval) should be delayed until the command is executed. So you could write something like
setlocal enabledelayedexpansion
FOR /D %%d IN ("D:\Folder*") DO (
SET "fld=%%d"
FOR /R "!fld!\logs" %%i IN (*) do echo %%i
)
BUT this will also not work, for the same reason indicated in the first code. The value to use in /R
is required at parse time.
So, how to solve the problem?
You can avoid having to indicate the folder in the /R
by first changing the current active directory to the folder being iterated by for /D %%i
for /d %%d in ("d:\Folder*") do (
pushd "%%~fd\logs" && (
for /r %%i in (*) do echo %%i
popd
)
)
or you can place the inner loop in a separate subroutine
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
or you can replace the inner recursive for
with a for /f
processing a recursive dir
for /d %%d in ("d:\Folder*") do (
for /f "delims=" %%i in ('dir "%%~fd\logs" /a-d /b /s`) do echo %%i
)
You could also just simplify it.
For /D %%A In ("D:\Folder*") Do Where/R "%%~A" *