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! ==>