Windows 批处理文件中延迟扩展的示例
有人能给我举个例子,说明批处理脚本在有或没有延迟扩展的情况下会有不同的行为吗?是否存在不希望使用延迟扩展的情况?谢谢。看看下面的例子 示例1:以下代码不使用延迟展开,因此for循环中的变量只展开一次。这意味着在循环的每次迭代中,Windows 批处理文件中延迟扩展的示例,windows,batch-file,cmd,environment-variables,delayedvariableexpansion,Windows,Batch File,Cmd,Environment Variables,Delayedvariableexpansion,有人能给我举个例子,说明批处理脚本在有或没有延迟扩展的情况下会有不同的行为吗?是否存在不希望使用延迟扩展的情况?谢谢。看看下面的例子 示例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% )
%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
Count = 1
Count = 2
Count = 3
Count = 4
这不是这个循环应该如何工作的
示例2:另一方面,如果我们使用延迟扩展,我们有以下脚本,它将按预期运行
setlocal ENABLEDELAYEDEXPANSION
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
Count = 1
Count = 2
Count = 3
Count = 4
当您使用
启用DelayedExpansion
并使用展开变量时
而不是%
,变量每次都会重新展开,并且一切都按预期进行。我想添加一个很好的示例,说明“EnableDelayedExpansion”(EDE)在无处不在的FOR循环示例之外是如何有用的
下面是我希望解析的一行地震数据(我称之为1line.txt)
AKU 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%
ECHO关闭
setlocal enableDelayedExpansion
设置其中=72
set/p line=给出了一个示例,说明批处理脚本在有或没有延迟扩展的情况下会有不同的行为
为了完整起见,让我们回答问题的另一部分,并展示一种情况,当您的数据包含感叹号时,您不希望使用延迟扩展代码>(并显示处理此类数据的两种方法):
请注意,上面的脚本显示
%%
百分号由%%
加倍(延迟扩展无关紧要),以及
代码>感叹号如果启用了延迟扩展:
“^!”
如果包含在一对双引号中,则使用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!
==>
正如答案中所指出的,延迟扩展的主要用途是设置和访问括号中的变量
尽管它在其他情况下也很有用
参数化子字符串和字符串替换:
输出将是:
#string#
#test text value#
first attempt:
"first argument"
"first argument"
second attempt:
"second argument"
"third argument"
虽然这可以通过额外的调用来实现,但这种方式更有效
使用括号内的shift命令参数化参数访问
输出将是:
#string#
#test text value#
first attempt:
"first argument"
"first argument"
second attempt:
"second argument"
"third argument"
正如您所见,参数化参数访问只能通过延迟扩展来完成
用于参数化的标记(或函数参数)
混合的另一种方法
s和%
s这对嵌套循环很有用:
@echo off
setlocal enabledelayedexpansion
set begin=2
set end=2
set string=12345
for /f "tokens=1,2" %%A in ("!begin! !end!") do set "string2=!string:~%%A,%%B!"
echo !string2!
endlocal
正如您现在看到的,for命令标记被用作参数。很好的示例。但更好的方法是使用set/A COUNT=COUNT+1
或更短的set/A COUNT+=1
证明在算术表达式中,变量可以仅用名称引用。算术表达式是set/A
之后的字符串。在命令提示窗口中运行时的帮助输出set/?
解释了IF和a的延迟扩展,例如,以及算术表达式中的特殊变量解析。值得澄清的是,在解析行时,以及在由括号分隔的块(例如IF
blocks)的情况下,会发生扩展整个区块算作一条“线”()。