The for
command (like the if
command) is parsed earlier than other commands. At this time, for
variable references like %%f
are not yet recognised. So for /R
cannot use a root path containing a for
variable reference like %%f
. The same is true for the option string of for /F
. You can also not use a delayed expanded variable instead of %%f
.
The easiest work-around for the script at hand is to use pushd
"%filepath%\%%f\docs"
before the for /R
loop and popd
after it, and to let for /R
use its default root, namely the current working directory, which has just been set by pushd
; the previous one becomes restored by popd
. Here is a demonstration of what I mean:
set "filepath=%~1"
for /F %%f in ('dir /A:D /B "%filepath%"') do (
if exist "%filepath%\%%f\docs" (
pushd "%filepath%\%%f\docs"
for /R %%r in ("*.docx") do (
echo/%%f
copy "%%~r" "%cd%\edited"
)
popd
)
)
An alternative but more complicated way is to move the for /R
loop into a sub-routine, to call it by the call
command and to pass the root path as an argument, like this:
set "filepath=%~1"
for /F %%f in ('dir /A:D /B "%filepath%"') do (
if exist "%filepath%\%%f\docs" (
call :SUB "%filepath%\%%f\docs"
)
)
goto :EOF
:SUB
for /R "%~1" %%r in ("*.docx") do (
echo/%%f
copy "%%~r" "%cd%\edited"
)
goto :EOF
Reference this post: How does the Windows Command Interpreter (CMD.EXE) parse scripts?