批处理文件遇到“文件夹”在“For”循环中未被识别为命令的问题

问题描述 投票:0回答:1

我写了一个简单的批处理来遍历源文件夹,列出每层下的所有子文件夹名称和文件名, 并将文件夹结构复制到目标文件夹。 对每个子文件夹下的单个文件进行后续操作是一个前期工作,因此请使用 For 循环而不是 Xcopy/copy 命令。而且效果很好。

setlocal EnableDelayedExpansion
set srcFolder=C:\dDrv\
set desFolder=C:\Test\
call :traverse
goto SUCCESS

:traverse
for /d %%D in ("%srcFolder%\*") do (
    echo Folder: %%~nxD
    echo %desFolder%
    IF not exist "%desFolder%\%%~nxD" (
        echo; Create folder "%desFolder%\%%~nxD"
        mkdir %desFolder%\%%~nxD
    )
    for %%F in ("%%D\*") do (
        echo File: %%~nxF
    )
    REM current %%D=%srcFolder%\%%D
    set "srcFolder=%%D"
    set "desFolder=%desFolder%\%%~nxD"
    echo %desFolder%
    
    call :traverse
)

但是,当我尝试使用以下参数修改子函数时。

.........
call :traverse %srcFolder% %desFolder%
goto SUCCESS

:traverse
set source=%~1
set target=%~2
for /d %%D in ("%source%\*") do (
    echo Folder: %%~nxD
    IF not exist "%target%\%%~nxD" (
        echo; Create folder "%target%\%%~nxD"
        mkdir %target%\%%~nxD
    )
     for %%F in ("%%D\*") do (
         echo File: %%~nxF
     )
    REM current %%D=%source%\%%D
    set "source=%%D"
    set "target=%target%\%%~nxD"
    call :traverse !source! !target!
)

它遭受类似的消息

'%MY Folder%' is not recognized as an internal or external command, operable program or batch file.
当遍历到每个子文件夹时,尽管它仍然有效。

我不知道为什么“in ("%srcFolder%*")”可以被视为上面一个FOR循环中的文件夹, 而“in ("%source%*")”不能被视为文件夹并显示错误消息。 在“为了/?”帮助,似乎 (set) 可以是一组文件。 我想弄清楚真正的原因是什么 最好让我知道如何调试这种语法/使用错误? 谢谢并感谢您的耐心等待。

for-loop batch-file syntax
1个回答
0
投票

要解决此问题,您可以在循环内启用延迟扩展并直接使用

!source!
!target!
,而不需要
call
语句。

这是修改后的代码:

setlocal EnableDelayedExpansion

set "srcFolder=C:\dDrv\"
set "desFolder=C:\Test\"
call :traverse "%srcFolder%" "%desFolder%"
goto SUCCESS

:traverse
set "source=%~1"
set "target=%~2"
for /d %%D in ("%source%\*") do (
    echo Folder: %%~nxD
    IF not exist "%target%\%%~nxD" (
        echo Create folder "%target%\%%~nxD"
        mkdir "%target%\%%~nxD"
    )
    for %%F in ("%%D\*") do (
        echo File: %%~nxF
    )
    set "source=%%D"
    set "target=%target%\%%~nxD"
    for %%D in ("!source!\*") do (
        set "current=%%~nxD"
        set "newTarget=!target!"
        echo Entering folder: !current!
        call :traverse "%%D" "!newTarget!"
    )
)

:SUCCESS

在此代码中,我删除了

call
语句并将第二个循环直接移至主循环中。这样,可以一致地使用延迟扩展,并且在每次迭代中正确更新变量。

请记住,使用

setlocal EnableDelayedExpansion
可能会产生一些副作用,特别是当您的批处理脚本涉及特殊字符或感叹号时。

© www.soinside.com 2019 - 2024. All rights reserved.