批处理文件中延迟扩展的示例
请看下面的例子...
实施例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
,并使用!
代替%
展开变量,该变量每次再膨胀,和一切按照它应该的方式工作。
我想添加一个很好的例子,说明“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将首先转换由%括起来的变量,然后处理由!括起来的变量!和(在这种情况下)将结果推送到“定位”变量。
尽管与问题没有直接关系,但这是我唯一可以通过传入变量来找到如何删除子字符串的地方,以及!和%的正确顺序是什么,所以谢谢: ) –
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!
==>
仅适用于该中间部分和链接;自从我出生后,我一直在寻找这些信息。 – Andrew
好的例子。但更好的办法是使用'set/A COUNT = COUNT + 1'或更短的'set/A COUNT + = 1'来证明在__算术表达式中___变量可以用它们的名字来引用。 __arithmetic表达式___是'set/A'之后的字符串。在命令提示符窗口'set /?'中运行的帮助输出解释了__IF__和__FOR__示例的延迟扩展以及算术表达式中的特殊变量解析。 – Mofi