batch file中延迟扩展的示例

有人可以给我一个例子,说明批处理脚本的行为有没有延迟扩展? 有没有什么情况下你不想使用延迟扩展? 谢谢。

看下面的例子

示例1:以下代码不使用延迟扩展,因此for循环中的variables只展开一次。 这意味着无论我们如何使用set命令, %Count%在每次迭代循环中总是会扩展为0

 @echo off set COUNT=0 for %%v in (1 2 3 4) do ( set /A COUNT=%COUNT% + 1 echo Count = %COUNT% ) pause 

所以这个脚本会输出:

 Count = 0 Count = 0 Count = 0 Count = 0 

这不是这个循环应该如何工作。

例2:另一方面,如果我们使用延迟扩展,我们有以下脚本,它将按预期运行。

 setlocal ENABLEDELAYEDEXPANSION set COUNT=0 for %%v in (1 2 3 4) do ( set /A COUNT=!COUNT! + 1 echo Count = !COUNT! ) pause 

而且,正如所料,它会输出:

 Count = 1 Count = 2 Count = 3 Count = 4 

当您使用ENABLEDELAYEDEXPANSION ,并使用扩展variables! 而不是% ,variables每次都被重新展开,一切都按照原来的方式工作。

我想添加一个很好的例子,说明“EnableDelayedExpansion”(EDE)如何在无处不在的FOR循环示例之外有用。

这里是我想parsing的一系列地震数据(我把它称为1line.txt)

ak_11574812 2015.04.29.193822 62.9525 -148.8849 1.0 9.5 1 49km S,Cantwell,Alaska

我碰到的问题是这条线的最后一段并不总是以相同的列号开始。 所以我需要创build一个灵活的SET命令,准确地取出这一行的最后一段。

 ECHO OFF setlocal enableDelayedExpansion set where=72 set /p line=<1line.txt set locate=!line:~%where%,28! echo %locate% 

EDE允许我在另一个variables(行)内放置一个variables(where)。 EDE将首先转换由%括起来的variables,然后处理由!括起来的variables! (在这种情况下)将结果推送到“定位”variables中。

马克斯的回答给出了一个例子,批处理脚本在不pipe有没有延迟扩展的情况下都会起作用

为了完整起见,让我们回答问题的另一部分,并展示在数据中包含感叹号时不希望使用延迟扩展的情况! (并且显示处理这种数据的两种方式):

 @ECHO OFF SETLOCAL EnableExtensions DisableDelayedExpansion set "_auxFile=%temp%\%~n0.txt" rem create multiline sample file >"%_auxFile%" ( for /L %%G in (1,1,3) do echo line %%G is 100%% valid! Sure! Hurrah!) rem create one-line sample file >"%_auxFile%" echo this line is 100%% valid! Sure! Hurrah! echo( echo --- file content type "%_auxFile%" echo( SETLOCAL EnableDelayedExpansion echo --- enabled delayed expansion chokes down unescaped exclamation marks^^^! "^!" for /F "usebackq delims=" %%G in ("%_auxFile%") do ( set "_auxLine=%%~G" echo loop var=%%~G echo _auxLine=!_auxLine! ) ENDLOCAL echo( SETLOCAL DisableDelayedExpansion echo --- toggled delayed expansion works although might be laborious! for /F "usebackq delims=" %%G in ("%_auxFile%") do ( set "_auxLine=%%G" echo loop var=%%G SETLOCAL EnableDelayedExpansion echo _auxLine=!_auxLine! ENDLOCAL ) ENDLOCAL echo( SETLOCAL DisableDelayedExpansion echo --- keep delayed expansion DISABLED: use CALL command! for /F "usebackq delims=" %%G in ("%_auxFile%") do ( set "_auxLine=%%G" echo loop var=%%G call :ProcessVar ) ENDLOCAL rem delete the sample file del "%_auxFile%" ENDLOCAL goto :eof :ProcessVar echo _auxLine=%_auxLine% echo WARNING: neither !_auxLine! nor %%G loop variable is available here! goto :eof 

请注意,上面的脚本显示了正确的转义方式

  • 百分号符号百分号加倍(延迟扩展无关紧要)
  • ! 感叹号如果延迟扩展启用:
    • "^!" 如果用一对双引号括起来,则使用cmd和批处理脚本一般的转义字符^ caret;
    • ^^^! 否则,使用三个^插入。

输出

 ==> D:\bat\SO\10558316.bat --- file content this line is 100% valid! Sure! Hurrah! --- enabled delayed expansion chokes down unescaped exclamation marks! "!" loop var=this line is 100% valid Hurrah _auxLine=this line is 100% valid Hurrah --- toggled delayed expansion works although might be laborious! loop var=this line is 100% valid! Sure! Hurrah! _auxLine=this line is 100% valid! Sure! Hurrah! --- keep delayed expansion DISABLED: use CALL command! loop var=this line is 100% valid! Sure! Hurrah! _auxLine=this line is 100% valid! Sure! Hurrah! WARNING: !_auxLine! as well as %G loop variables are not available here! ==>