4.2 环境变量延迟扩展(下)

2022-04-13 15:07 更新

《批处理入门手册》
四. 环境变量延迟扩展(下)
-----------------------------------------------------------------------------------------------------
4.2 学习环境变量延迟扩展

学习要点:
三,批处理延迟变量(通俗解释)
四,什么时候使用延迟变量?如何使用?
-----------------------------------------------------------------------------------------------------


三,批处理延迟变量(通俗解释)
原文地址:http://bbs.bathome.cn/viewthread.php?tid=354

  变量延迟  setlocal EnableDelayedExpansion
  一个让大多数新手头痛的问题,网上教程虽多,但多半都是看不懂的,里面的专业术语太多。
以 cn-dos 联盟的willsort的这篇教程为例,(个人认为是解释的极具权威和专业的)
http://www.cn-dos.net/forum/viewthread.php?tid=20733

  但可能就是因为专业,所以才看不懂,因为学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  那么如何实现呢?将上例修改如下,

例4,


@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你也能分析得出来吧?
-----------------------------------------------------------------------------------------------------

 


注:以上文章在编辑整理时稍有修改!
Januapr编辑于2009-09-15 星期二14:48:57.46


以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号