在带有enabledelayedexpansion的for循环中使用时,变量在if语句中不起作用

时间:2015-11-08 21:53:41

标签: windows batch-file if-statement for-loop

我有一个带有MS Windows更新名称的文本文件:

...
KB3072019
KB3044374
KB3011780
KB3083711
...

有一个带

的文件夹

downloaded updates

我的目标是根据文本文件检查是否下载了更新。

@echo off
set /a x=0
setlocal ENABLEDELAYEDEXPANSION

for /F "tokens=*" %%A in (d:\WindowsUpdate.log) do (
set /a x=x+1
echo Update number !x!, name %%A, state:
IF EXIST d:\!Del\Win8Updates_x64\Merged\*%%A*.cab (echo Downloaded) ELSE (echo MISSING!)
)
pause

输出应该是这样的:

Update number 83, name KB3045999, state:
MISSING
Update number 84, name KB3045746, state:
Downloaded
Update number 85, name KB3066441, state:
Downloaded
Update number 86, name KB3071663, state:
MISSING

但实际上它看起来像这样:

Update number 83, name KB3045999, state:
MISSING
Update number 84, name KB3045746, state:
MISSING
Update number 85, name KB3066441, state:
MISSING
Update number 86, name KB3071663, state:
MISSING

我的问题:为什么%% A在if语句中不起作用?

重要提示:我不想跳过这些行号,因为它们代表了更新的顺序。稍后我将修改脚本以将现有更新复制/移动到另一个前缀为其前缀的位置,例如 83_windows8.1-kb3045999-x64.cab

1 个答案:

答案 0 :(得分:1)

有一个包含感叹号的路径d:\!Del会导致问题,因为启用延迟展开后,!会被删除。对于回显的文本MISSING!也是如此。临时删除@echo off将允许您在检查输出时看到该行为。

为避免这种情况,有(至少)以下选项:

  1. 转义惊叹号:

    @echo off
    set /A x=0
    setlocal EnableDelayedExpansion
    
    for /F "tokens=*" %%A in (d:\WindowsUpdate.log) do (
        set /A x+=1
        echo Update number !x!, name %%A, state:
        if exist "d:\^!Del\Win8Updates_x64\Merged\*%%A*.cab" (
            echo Downloaded
        ) else (
            echo MISSING^^!
        )
    )
    endlocal
    pause
    
  2. 暂时禁用延迟扩展:

    @echo off
    set /A x=0
    setlocal EnableDelayedExpansion
    
    for /F "tokens=*" %%A in (d:\WindowsUpdate.log) do (
        set /A x+=1
        echo Update number !x!, name %%A, state:
        setlocal DisableDelayedExpansion
        if exist "d:\!Del\Win8Updates_x64\Merged\*%%A*.cab" (
            echo Downloaded
        ) else (
            echo MISSING!
        )
        endlocal
    )
    endlocal
    pause
    
  3. 仅在需要时启用延迟扩展:

    @echo off
    set /A x=0
    setlocal DisableDelayedExpansion
    
    for /F "tokens=*" %%A in (d:\WindowsUpdate.log) do (
        set /A x+=1
        setlocal EnableDelayedExpansion
        echo Update number !x!, name %%A, state:
        endlocal
        if exist "d:\!Del\Win8Updates_x64\Merged\*%%A*.cab" (
            echo Downloaded
        ) else (
            echo MISSING!
        )
    )
    endlocal
    pause