我很困惑这里发生了什么。它应该将从docs找到的所有docx复制到工作目录。但由于某种原因,for循环中的%% f显示为%f。我做了一个回声,它打印出文件夹就好了。同样的事情也发生在%% r和%r上。我是不是写错了?
set filepath=%1
for /f %%f in ('dir /ad /b %filepath%') do (
if exist "%filepath%\%%f\docs" (
for /r %filepath%\%%f\docs %%r in (*.docx) do (
echo %%f
copy %%r "%cd%\edited"
)
)
)
输出
if exist "C:\Documents\WordDocs\Data1\docs" (for /R C:\Documents\WordDocs\%f\docs %r in (*.docx) do (
echo Data1
copy %r "C:\Users\admin\Desktop\Test"
) ) )
答案 0 :(得分:2)
for
command(与if
command一样)比其他命令更早解析。目前,for
等%%f
变量引用尚未被识别。因此,for /R
无法使用包含for
变量引用的根路径,例如%%f
。 for /F
的选项字符串也是如此。您也不能使用delayed expanded variable代替%%f
。
手头脚本最简单的解决方法是在"%filepath%\%%f\docs"
循环之前使用pushd
for /R
,然后在popd
之后使用for /R
。{{1}使用它的默认根,即当前工作目录,它刚刚由pushd
设置;前一个由popd
恢复。以下是我的意思:
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
)
)
另一种更复杂的方法是将for /R
循环移动到子例程中,由call
command调用它并将根路径作为argument传递,如这样:
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
参考这篇文章:How does the Windows Command Interpreter (CMD.EXE) parse scripts?
答案 1 :(得分:1)
此版本不使用For /R
:
For /F "Delims=" %%A In ('Dir/B/AD-L "%~1"') Do If Exist "%~1\%%A\docs\" (
For /F "Delims=" %%B In ('Dir/B/S/A-D-L "%~1\%%A\docs\*.docx"'
) Do Echo=Copy "%%~B" "%CD%\edited")
Pause
如果您对cmd窗口中的输出感到满意,记住未编辑您的目的地路径,请删除第3行的第4行和Echo=
。