批处理文件中延迟扩展的示例

Nei*_*her 43 cmd batch-file delayedvariableexpansion

有人可以给我一个例子,说明批处理脚本在有或没有延迟扩展的情况下会有不同的行为吗?您是否有任何不希望使用延迟扩展的情况?谢谢.

Max*_*Max 57

看看下面的例子......

示例1:以下代码不使用延迟扩展,因此for循环中的变量仅扩展一次.这意味着无论我们使用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
Run Code Online (Sandbox Code Playgroud)

所以这个脚本将输出:

Count = 0
Count = 0
Count = 0
Count = 0
Run Code Online (Sandbox Code Playgroud)

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

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

setlocal ENABLEDELAYEDEXPANSION
set COUNT=0

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

pause
Run Code Online (Sandbox Code Playgroud)

并且,正如预期的那样,它将输出:

Count = 1
Count = 2
Count = 3
Count = 4
Run Code Online (Sandbox Code Playgroud)

当你使用ENABLEDELAYEDEXPANSION,而!不是使用扩展变量%时,每次都会重新扩展变量,并且一切都按预期工作.

  • 很好的例子。但更好的是使用 `set /A COUNT=COUNT + 1` 或更短的 `set /A COUNT+=1` 来证明在 __arithmetic expression__ 变量中可以只用它们的名字来引用。__算术表达式__是`set /A`之后的字符串。在命令提示符窗口“set /?”中运行的帮助输出解释了 __IF__ 和 __FOR__ 示例的延迟扩展以及算术表达式中的特殊变量解析。 (3认同)

小智 9

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

这是我要解析的一系列地震数据(我称之为1line.txt)

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

我遇到的问题是这一行的最后一段并不总是从同一列号开始.所以我需要创建一个灵活的SET命令,准确地拔出这一行的最后一段.

ECHO OFF
setlocal enableDelayedExpansion
set where=72
set /p line=<1line.txt
set locate=!line:~%where%,28!
echo %locate%
Run Code Online (Sandbox Code Playgroud)

EDE允许我将变量(where)放在另一个变量(行)中.EDE将首先将变量括在%括号中,然后处理由括号​​括起来的变量!和(在这种情况下)将结果推出到"locate"变量.


Jos*_*efZ 8

Max的答案给出了一个示例,说明批处理脚本在有或没有延迟扩展的情况下会有不同的行为.

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

@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
Run Code Online (Sandbox Code Playgroud)

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

  • %通过%%加倍百分号(延迟扩张无关紧要),和
  • ! 感叹号如果启用了延迟扩展:
    • "^!"如果用一对双引号括起来,那么使用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!

==>
Run Code Online (Sandbox Code Playgroud)

  • 仅为该中间部分和链接+1; 自从我从子宫出现以来,我一直在寻找这些信息. (2认同)