2012-05-11 28 views

回答

43

请看下面的例子...

实施例1:下面的代码不使用延迟扩展,所以for循环中的变量被扩展一次。这意味着,%Count%总会扩大到0在循环中,每次迭代无论我们做什么,以使其与set命令:

@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,并使用!代替%展开变量,该变量每次再膨胀,和一切按照它应该的方式工作。

+0

好的例子。但更好的办法是使用'set/A COUNT = COUNT + 1'或更短的'set/A COUNT + = 1'来证明在__算术表达式中___变量可以用它们的名字来引用。 __arithmetic表达式___是'set/A'之后的字符串。在命令提示符窗口'set /?'中运行的帮助输出解释了__IF__和__FOR__示例的延迟扩展以及算术表达式中的特殊变量解析。 – Mofi

7

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

这里是地震数据的线,我希望解析(I称之为它1line.txt)

ak_11574812 2015.04.29.193822 62.9525 -148.8849 1.0 9.5 1个49公里坎特维尔的S,阿拉斯加

我遇到的问题是该行的最后一部分并不总是始于相同的列号。所以我需要创建一个灵活的SET命令来精确地截取这一行的最后一部分。

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

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

+0

尽管与问题没有直接关系,但这是我唯一可以通过传入变量来找到如何删除子字符串的地方,以及!和%的正确顺序是什么,所以谢谢: ) –

7

Max's answer给出一个批处理脚本的行为不同或不带延迟扩展的示例

为了完整起见,让我们回答这个问题的另一部分,并显示一个情况下,你不会想使用延迟扩展当您的数据包含一个感叹号!(和显示处理这些数据的两种方式) :

@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 

注意,上述脚本显示proper ways of escaping

  • %百分号通过%%它加倍(延迟expansi就无所谓),并且
  • !感叹号如果延迟扩展开启:
    • "^!"如果封闭在一对双引号,然后使用cmd和批处理脚本的通用转义符^插入符号;
    • ^^^!否则,使用三个^插页。

输出

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

==> 
+0

仅适用于该中间部分和链接;自从我出生后,我一直在寻找这些信息。 – Andrew

相关问题