一,什么是延迟环境变量扩展?
延迟变量全称"延迟环境变量扩展",要理解这个东西,我们还得先理解一下什么叫变量扩展!
CMD在解释我们的命令的时候,首先会读取一条完整的命令,然后对其进行一些命令格式的匹配操作,看你所输入的
命令格式是不是符合它的要求.如果我们要在命令中引用一些变量,那么我们如何让CMD在解释我们的命令时,能识别
出这个变量呢"htmlcode">
@echo off set var=test echo %var% pause
CMD在读取到echo %var%这句命令后,就会进行匹配操作,它马上就发现var字符两边有%号,这时CMD就会把它当作一
个变量处理,查看这个var变量名是不是有值,如果有就用该值把变量名var给替换掉,这里我们的var在上一条命令set
var=test中,给var赋值为test,所以CMD会用test把%var%这个变量名替换掉,替换后的结果就为echo test了.这些步
骤都是CMD进行匹配操作的步骤,匹配完后,他再执行echo test这条语句,这时我们的CMD中就会echo出一个test了.
什么是环境变量扩展知道了,那什么是延迟环境变量扩展呢"一条完整的命令",在BAT中,IF
FOR这样的命令都可以加括号,将一些命令嵌套在里面执行.这样的话对于一条可以加扩号嵌其他命令的命令,他的完
整格式就是for %%i in (....)这样一个整体.此时,如果我们如果在括号里面嵌入一些设置变量值的命令,就会出现
问题了!
例2,
@echo off for /l %%i in (1,1,5) do ( set var=%%i echo %var% ) pause
执行后会显示5个空行的错误提示!为什么"延迟环境变量扩展",这个概念就被提出来了。
在批处理中,我们可以用setloacl enabledelayedexpansion 这个命令来启用"延迟环境变量扩展" ,在我们启用
了"延迟环境变量扩展"后,当CMD在解释含有嵌套格式的命令时,他会把嵌套的命令一条一条的先执行一次,然后再进
行匹配操作,这样我们的赋值操作就会完成.并且在"延迟环境变量扩展"启用后,CMD会用!号来判断这是不是一个变量
。如没启用前变量用%name%这样的格式判断,启用后就用!name!这样的格式判断了,这个符号我们需要注意!
例3,
@echo off setlocal enabledelayedexpansion set var=1 for /l %%i in (1,1,5) do ( set /a var =%%i echo !var! ) pause
这样大家应该明白什么是延迟环境变量扩展了吧.再来一个例子
例4,
@echo off set var=test & echo %test% pause
这条命令放在一行,表示他是一条完整的命令,不启用"延迟环境变量扩展",就会出现上面的赋值错误!改成下这样就
OK了:
@echo off setlocal enabledelayedexpansion set var=test & echo !var! pause
二,批处理变量延迟详解
关于环境变量延迟扩展,使用set /"htmlcode">
@echo off & setlocal EnableDelayedExpansion for /f "tokens=* delims=" %%i in ("Hello world.") do ( set n=%%i set n=!n:ld.=t! set n=!n:o w= S! set n=!n:He=Wi! echo !n! ) Pause
将上面代码保存为.bat双击执行后会显示“Will Sort”字符串,下面将讲解每个语句的意思:
1.@echo off & setlocal EnableDelayedExpansion
关闭命令回显,并启用变量延迟
2.for /f "tokens=* delims=" %%i in ("Hello world.") do ( )
for命令及其参数的使用,请大家在论坛里搜索相关字眼。限于篇幅问题,这里不作讨论。如果此时你不明白它的意
思,那么你就当它的作用是把字符串“Hello world.”赋值给%%i好了,当然这只是权宜之计,以后一定要学习for
的使用!
3.set n=%%i
把%%i的值(即Hello world.)赋予给变量n,这个大家都知道吧
4.set n=!n:ld.=t!
这里要讲讲set替换字符的功能了。这个语句的意思是,先获取变量n的值(此时n的值是“Hello world.”),然后
将字符“t”替换字符“ld.”,然后再将替换后的结果再次赋值给变量n(此时n的值变为“Hello wort”)。至于
set替换字符的编写格式,大家可以在CMD键入“set/"htmlcode">
@echo off for /f "tokens=* delims=" %%i in ("Hello world.") do ( set n=%%i set n=%n:ld.=t% set n=%n:o w= S% set n=%n:He=Wi% echo %n% ) Pause
这和前面的例子差不多,只是所有!号都换成%号,这是个错误的例子。因为它没有启用变量延迟,也没有使用!
号把变量括起来。我们看到它的执行结果是显示“ECHO 处于关闭状态”。
为什么会这样呢?原因是,在没有启用变量延迟的情况下,凡是在括号内(即do里面)的变量,在执行for语句之前
,就已经被替换成for语句之前其它命令对该变量所赋予的值。
则是说在本例中的以下几句
set n=%%i set n=%n:ld.=t% set n=%n:o w= S% set n=%n:He=Wi% echo %n%
第一句能正常执行并达到它的目的,因为它只是单纯地将%%i的值赋予给变量n,所以没有任何问题。其它几句属
这样情况:早在for语句执行前,CMD就急不切待地将这几句里面的所有变量n一同执行替换行为,替换为for之前,
其它命令对n所设置的值,从而使n变成一个常量。但在本例中,for语句之前只有@echo off这句,并没有其它命令
对n作过任何赋值行为,所以在for之前,变量n的值为空值。
即是说,set n=%n:ld.=t% 这句里面的变量n,在CMD读取(注意是读取不是执行)完整个for语句后(这时还未轮
到set执行自己的任务),就立刻被替换为一个空值,一个空值里面没有任何东西,所以就不存在一字符替换另一字
符这种说法(没有东西怎么替换?)。最终到执行set n=%n:ld.=t%语句时,它只是获取一个空值,再给变量n赋予
空值而已。其它几句也是一样原理。
所以,最后echo %n%的时候变量n还是个空值,而echo命令没有东西可以显示,就只有显示“ECHO 处于关闭状态
”这句来说明自己的状态
通过这个例子的说明,相信大家已经知道变量延迟的作用吧!我们再回头来看看例1。
启用变量延迟后,在执行
set n=!n:ld.=t! set n=!n:o w= S! set n=!n:He=Wi! echo !n!
这些语句前,它们里面的变量n不会马上被CMD替换(启用延迟后,CMD变得有耐性啦^_^),而未被替换的话,那么n
就还是变量,而不是常量。等到执行set n=!n:ld.=t!等这几句时,变量n才被替换。这样每个set命令都能感知变量
n的任何变化,从而作出正确的替换行为。这就是变量延迟啦!
不要以为只有for才要用变量延迟,下面这个例子同样需要
例3,这是个错误的例子
@echo off set mm=girl&echo %mm% pause
执行后依然显示“ECHO 处于关闭状态”。
原因是没有启用延迟,而且在set mm=girl&echo %mm%语句前没有其它命令对mm进行赋值。这时当CMD执行set
mm=girl&echo %mm%语句前,就已经急不切待地把变量mm的值替换了,而又因为前面没给mm赋值,所以mm被替换为空
值,变成常量。等到echo命令执行时,它其实是echo一个不会变化的常量,本例中即是空值。
有人会问,echo前面不是给mm赋值了吗?
这个就要关系到CMD解释命令的步骤,大家可以参详本帖开头willsort的帖子。
总的来说是,如果不启用变量延迟,在本例中,echo是不会理会也不会知道,它前面(指同一行语句)是否有其
它命令给mm赋值。它只会从set mm=girl&echo %mm%这句以上的语句中获取它所要显示的变量的内容,也就是说,上
一行或上几行的命令将mm设置成什么值,echo命令就显示什么值。
大家这样做就明白了:
@echo off set mm=boy set mm=girl&echo %mm% pause
看看显示什么结果就知道了!
这样编写例3才正确:
@echo off&setlocal EnableDelayedExpansion set mm=girl&echo !mm! pause
开启了变量延迟,变量扩展(替换)的行为就推迟到echo命令执行时,这时echo能感知它前面的命令(本例的set)
对变量mm做了什么“坏事”,从而作出正确的判断并执行
三,批处理延迟变量(通俗解释)
变量延迟 setlocal EnableDelayedExpansion
一个让大多数新手头痛的问题,网上教程虽多,但多半都是看不懂的,里面的专业术语太多。
以 cn-dos 联盟的willsort的这篇教程为例,(个人认为是解释的极具权威和专业的)
但可能就是因为专业,所以才看不懂,因为学cmd批处理的并不一定都是学计算机专业的。这个鬼东西确实不太好
理解,在下也是摸爬滚打多时,总结出一点点经验,现用通俗的方法解释出来,希望能给新手些帮助,老鸟们见笑
了,若有不对的地方,欢迎指出。
言归正传
在什么时候需要延迟变量,和该如何引用延迟变量,我想这才是大多数新手迫切想要知道的问题。
耐心看完下面的内容,我想对你应该是有帮助的。
要想了解延迟变量,首先你要明白什么是“复合语句”好像又来了个“专业”名词,别急,这个超好理解。所谓
“复合语句”就是指一对()里的所有命令。比如for的do后面
如:
for /f "delims=" %%i in (a.txt) do ( set var=%%i echo %%i set num=%%i )
这里do后面的三句命令,在一对()里面,这就叫“复合语句”,当然不止for 还有if 等等。。。
如:
if "%var%"=="abc" ( echo ok set lis=123 )
反正就是凡是()里的所有命令,就叫“复合语句”
另外:这也是复合语句 set abc=123&echo %abc% 没错,通过管道命令&连接起来的命令,也是复合语句。
好,了解了复合语句,现在开始讲延迟变量,也就说,在复合语句中才要使用延迟变量。
我们先不去理解什么叫“变量的扩展”这玩意叫法太专业,我到现在都不太明白,
我们只要知道在什么时候需要使用延迟变量,如何才能正确提取到我们需要的变量就可以了,这才是我们的目的。
cmd在处理“复合语句”的时候,如果“复合语句”中用到了变量,会把变量的值当作复合语句之前变量的值来引用
。如果在此之前变量没有被赋值,就把它当成空值。
例1,
@echo off for /l %%i in (1 1 10) do ( set var=%%i echo %var% ) Pause
运行上面的代码,显示什么?显示10个echo处于关闭状态。按照逻辑,var的值应该依次是 1、2、3........10 才
对啊!
这就是因为没有开启 延迟变量 的缘故,cmd把var的值当作复合语句之前的值来引用,
而在本例中,复合语句之前并没有给var定义,所以var的值是空的,所以会显示10个echo处于关闭状态。
例2,
@echo off set var=abc for /l %%i in (1 1 10) do ( set var=%%i echo %var% ) Pause
运行上面的代码,会显示什么,大家应该知道了吧?
例3,
@echo off set var=abc for /l %%i in (1 1 5) do ( set var%%i=%%i echo %var% ) echo %var1% %var2% %var3% %var4% %var5% pause
运行上面的代码后,复合语句中所赋的值全部显示出来了,这说明什么呢?
说明,在复合语句中,并不是没有给变量赋值,只是你若没有开启延迟变量,你就没法在复合语句中提取到它,要
等复合语句运行完毕后,才能提取到。
变量的表示方法:两种: 1、%var% 2、!var!
第一种表示方法,大家都知道,第二种就是引用 延迟的变量。
在开启了延迟变量的情况下,如果在复合语句之外,用哪种方法表示都可以。但是你若要在复合语句中引用复合语
句即时得到的变量,就要用第二种方法。看例子
例4,
@echo off setlocal EnableDelayedExpansion set var=abc for /l %%i in (1 1 10) do ( set var=%%i echo %var% echo !var! ) Pause
注意:例子中有两个echo 一个是显示 %var% 一个是显示 !var!
结果很明白了,%var% 显示的结果是复合语句之前变量var的值,而 !var! 显示的就是复合语句中即时得到的值。
例5,
@echo off setlocal EnableDelayedExpansion for /l %%i in (1 1 5) do ( set var%%i=%%i ) echo %var1% %var2% %var3% %var4% %var5% echo !var1! !var2! !var3! !var4! !var5! pause
这个例子说明什么,不用再解释了吧?
说明在开启了延迟变量的情况下,且在复合语句之外,用两种方法都可以表示变量。就说到这吧。以上的解释,完
全是出于个人的理解,也是为方便非专业人士理解,解释肯定有错误的地方、就象学习英语时,为方便记忆,用汉
字的读音来作解释一样。呵呵,是一种“偏门”各位新手千万不要把以上所说的当成是“真理”,否则就变成是“
误人”了。
四,什么时候使用延迟变量?如何使用?
什么时候使用延迟变量?如何使用?这些一直是使新手困惑的地方,那到底是怎么样的呢?那请看下面的例子,
我们将一步步引导大家。
例1,
@echo off set /a num=0 for /l %%i in (1 1 3) do ( Rem ================================ set /a num =1 Rem 原意是变量num的值每次都加1 Rem ================================ echo %num% ) pause>nul
先猜猜看,运行之后的结果是什么呢?你是不是认为它会显示:1 2 3 呢?我想大部分人会这么认为。你再将以
上代码保存为批处理文件,运行,看看结果。
你会看到,显示的结果并不是意料中的 1 2 3 而是 0 0 0,这个是为什么呢?
原来这个是因为,批处理在处理for 或者if 语句中的变量时,先要进行预处理,把其中的用%%括起来的变量,先
替换为语句之前的变量(如上面的代码,for语句中的%num%早就被替换为语句前的 值:0),所以,for语句运行时
,虽然已经给变量加了1,但是,值却不变(因为echo %num%中的%num%早已被替换为:0了)。
那么,要实现(for或者if)语句中的变量实时的变化(如这里,我就要将1 2 3 显示出来)要怎么办呢?那就要起
用延迟变量,先在批处理中申明:setlocal enabledelayedexpansion 然后,将语句:echo %num%改成!num!(也就
是将“%”改成“!”),这样就可以达到效果了,演示代码:
例2,
@echo off Rem ''''///////下面先申明起用延迟变量///////////// setlocal enabledelayedexpansion set /a num=0 for /l %%i in (1 1 3) do ( Rem ================================ set /a num =1 Rem 变量num的值每次都加1 Rem ================================ Rem '''''''//////////////////下面的变量不能再用"%"括起来,而应该用"!"//////////// echo !num! ) pause>nul
归纳总结:
1、为什么要用延迟变量?
让if语句和for语句中的变量实时变化;
2、什么时候用延迟变量?
一般是用在 for 语句和 if 语句中;
3、怎么用延迟变量?
先在批处理中申明起用延迟变量:setlocal enabledelayedexpansion
然后将 for 语句、if语句中的变量用两个"!"括起来即可
4、其实在使用变量嵌套变量也可以使用变量延迟的。
例3,
@echo off set a=1 set b1=10 echo %b%a%% pause
执行显示,得到 %b1%
其实我想得到的是 赋予b1的值,即 10 那么如何实现呢"htmlcode">
@echo off set a=1&set b1=10 call,echo %%b%a%%% pause>nul
call 这里实际是对命令行进行重新组织扩展,先扩展%%b%a%%%里面的%a%,使%a%变成a的值1,再用cal来扩展%b1%
。
也可以用变量延迟来实现,方法如下:
例5,
@echo off set /a a=1,b1=10 Setlocal EnableDelayedExpansion echo:!b%a%! ... pause
call 在这里的用法实际是变量延迟的一种快捷方式,变量延迟一般用在for的循环体里面。
call,%%b%a%%% 这里的逗号实际是一个分隔符,和空格一样,还有很多分隔符可用,比如上例中的 echo:!b%a%! ,
当然并不是所有的命令都可以这样用,看情况而定……
例6,
@echo off&setlocal enabledelayedexpansion set a=1000 set b=dd set a%b%=9000 set c=!a%b%! echo %c% pause
执行一下,看看显示的将是什么?为什么是这样?相信通过例4,例5你也能分析得出来吧?
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]