代码之家  ›  专栏  ›  技术社区  ›  sergiol

FOR将在命令行中设置变量,但不在批处理文件中[重复]

  •  0
  • sergiol  · 技术社区  · 6 年前

    有人能给我一个例子,说明在延迟扩展或不延迟扩展的情况下,批处理脚本的行为会有所不同吗?是否存在不希望使用延迟扩展的情况?谢谢。

    0 回复  |  直到 10 年前
        1
  •  59
  •   carlossierra    8 年前

    看看下面的例子。。。

    例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 ,并使用 ! 而不是 % ,变量每次都会重新展开,并且一切都按预期工作。

        2
  •  9
  •   Bruce Sinkula    9 年前

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

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

    阿克苏11574812 2015.04.29.193822 62.9525-148.8849 1.0 9.5阿拉斯加州坎特韦尔以南149公里

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

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

    EDE允许我将一个变量(where)放在另一个变量(line)中。EDE将首先翻译用%括起来的变量,然后处理用%括起来的变量!然后(在本例中)将结果推送到“locate”变量中。

        3
  •  8
  •   Community    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

    • % 百分比签字人 %% 加倍(延迟扩展不重要),并且
    • ! 启用延迟扩展时的感叹号:
      • "^!" 如果包含在双引号中,则使用 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!
    
    ==>