Board logo

标题: [原创] 批处理延迟变量(通俗解释) [打印本页]

作者: 随风    时间: 2007-12-14 16:52     标题: 批处理延迟变量(通俗解释)

延迟变量详解(通俗解释)
:: by 随风 @bbs.bathome.net  2007-12-14
变量延迟  setlocal EnableDelayedExpansion
一个让大多数新手头痛的问题,网上教程虽多,但多半都是看不懂的,里面的专业术语太多。
以 cn-dos 联盟的willsort的这篇教程为例,(个人认为是解释的极具权威和专业的)
http://www.cn-dos.net/forum/viewthread.php?tid=20733&fpage=1&highlight=%E5%BB%B6%E8%BF%9F
但可能就是因为专业,所以才看不懂,因为学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:
  1. @echo off
  2. for /l %%i in (1 1 10) do (
  3.     set var=%%i
  4.     echo %var%
  5. )
  6. pause
复制代码
运行上面的代码,显示什么?显示10个echo处于关闭状态。
按照逻辑,var的值应该依次是 1、2、3........10 才对啊!
这就是因为没有开启 延迟变量 的缘故,cmd把var的值当作复合语句之前的值来引用,
而再本例中,复合语句之前并没有给var定义,所以var的值是空的,所以会显示10个echo处于关闭状态。
再看例2:
  1. @echo off
  2. set var=abc
  3. for /l %%i in (1 1 10) do (
  4.     set var=%%i
  5.     echo %var%
  6. )
  7. pause
复制代码
运行上面的代码,会显示什么,大家应该知道了吧?
再看例3:
  1. @echo off
  2. set var=abc
  3. for /l %%i in (1 1 5) do (
  4.     set var%%i=%%i
  5.     echo %var%
  6. )
  7. echo %var1% %var2% %var3% %var4% %var5%
  8. pause
复制代码
运行上面的代码后,复合语句中所赋的值全部显示出来了,这说明什么呢?
说明,在复合语句中,并不是没有给变量赋值,只是你若没有开启延迟变量,
你就没法在复合语句中提取到它,要等复合语句运行完毕后,才能提取到。
变量的表示方法:两种:  1、%var%   2、!var!
第一种表示方法,大家都知道,第二种就是引用 延迟的变量。
在开启了延迟变量的情况下,如果在复合语句之外,用哪种方法表示都可以。
但是你若要在复合语句中引用复合语句即时得到的变量,就要用第二种方法。看例子
例4:
  1. @echo off
  2. setlocal EnableDelayedExpansion
  3. set var=abc
  4. for /l %%i in (1 1 10) do (
  5.     set var=%%i
  6.     echo %var%
  7.     echo !var!
  8. )
  9. pause
复制代码
注意:例子中有两个echo 一个是显示 %var% 一个是显示 !var!
结果很明白了,%var% 显示的结果是复合语句之前变量var的值,
而 !var! 显示的就是复合语句中即时得到的值。
再看例5
  1. @echo off
  2. setlocal EnableDelayedExpansion
  3. for /l %%i in (1 1 5) do (
  4.     set var%%i=%%i
  5. )
  6. echo %var1% %var2% %var3% %var4% %var5%
  7. echo !var1! !var2! !var3! !var4! !var5!
  8. pause
复制代码
这个例子说明什么,不用再解释了吧?
说明在开启了延迟变量的情况下,且在复合语句之外,用两种方法都可以表示变量。
就说到这吧。以上的解释,完全是出于个人的理解,也是为方便非专业人士理解,
解释肯定有错误的地方、就象学习英语时,为方便记忆,用汉字的读音来作解释一样。
呵呵,只是一种“偏门”一种理解的方法 ^_^。

[ 本帖最后由 随风 于 2010-5-2 17:23 编辑 ]
作者: 辉少    时间: 2007-12-14 23:13

学习了
谢谢

作者: smilediao    时间: 2007-12-15 18:20

非常好啊,我把它转到了我的空间去了,不介意吧,顺便给论坛做了个广告,
作者: 随风    时间: 2007-12-15 19:09

转转,随便转.
作者: zyz0304360    时间: 2008-2-9 23:28

解释的太好了

例子详细,通俗易懂

非常感觉楼主

受益非浅

谢谢了


作者: hsyxh    时间: 2008-2-25 21:38

我学习了,谢谢。确实较通俗。
作者: chchtype136    时间: 2008-3-21 06:01

顶............
作者: 9394    时间: 2008-3-23 00:54

全靠这帖帮我解决了大问题,谢
作者: jay006    时间: 2008-3-24 16:52

看懂了一点,但是我不知道能在哪里使用到这些语句,哪位能帮我举个列子说下```要简单点的列子````
作者: lovesunny    时间: 2008-11-18 21:23

看3边了,还有太多不明白~~
作者: MarkovChain    时间: 2008-11-30 04:26

通俗易懂,解释得灰常好
作者: jackelijie135    时间: 2009-3-15 16:51

果然名不虚传的通俗易懂版本!!O(∩_∩)O哈哈~
作者: 5810239q    时间: 2009-3-25 16:46

谢谢你的贴子!!!
作者: eduuuu    时间: 2009-7-13 21:26

能在介绍下 goto :eof 和延迟变量间的关系吗? 举个也通俗的例子学习学习.
作者: januapr    时间: 2009-8-8 22:55

顶一下楼主,讲得够明白,呵呵!
作者: hdw    时间: 2009-8-10 16:50

"复合语句"就是被()包裹在一起的多条命令,语句的集合
作者: hdw    时间: 2009-8-10 17:01     标题: 解释一下这句

“cmd在处理“复合语句”的时候,如果“复合语句”中用到了变量,
会把变量的值当作复合语句之前变量的值来引用。如果在此之前变量没有被赋值,就把它当成空值。”这样说更明白些“cmd在处理“复合语句”的时候,如果“复合语句”中用到了变量,变量就使用在执行复合语句之前给它(指变量)确定的值。如果变量没有赋值,认为变量为空。”
作者: 基拉freedom    时间: 2009-8-16 20:29

转转
不介意吧??
转到空间去 很明晰的教材
作者: msdlya    时间: 2009-11-19 02:23

随风老师写 的教材太精彩了。
批处理让我以前繁琐的工作变成了一键搞定的。
感谢老师的奉献精神。
看了这篇教材。以前很多不明白 的地方都明白了
作者: dkaily1314    时间: 2009-11-20 18:00

好贴,让我这个菜鸟长见识了
作者: friendtasy    时间: 2009-11-27 22:31

很好,有所了解,不过还需实例熟习
作者: hy55310    时间: 2009-12-15 12:11

解释的太好了!原来我一直都不知道在什么时候需要使用延迟变量,如何才能正确提取到我们需要的变量现在基本能够了解了。谢谢
作者: hy55310    时间: 2010-1-10 21:10

终于理解延迟变量的用法
1  开启了延迟变量的情况下,且在复合语句之外,用两种方法都可以表示变量。
2开启了延迟变量。要用、!var!
作者: caimingbing    时间: 2010-1-13 18:48

我打印出来,慢慢消化
作者: dahual    时间: 2010-3-8 22:29

willsort 的解释很专业,很本质!
楼主 的解释及给出的例子很好,学习。
作者: lvsehuaxue    时间: 2010-9-20 10:13     标题: 正为此感到头疼!

你就送来了灵丹妙药,能不叫人感谢!
作者: wangqi0077    时间: 2010-11-11 11:17

感谢随风大大..至少让我知道.复合语句要用变量的时候.才需要用到延迟.感谢.
作者: ft5126752    时间: 2010-12-7 21:45

内容怎么看不到
作者: lowprofile    时间: 2011-9-27 13:58

学习了。反复练习中/。。
作者: QIAOXINGXING    时间: 2011-10-8 15:37

不错,学习了
作者: Fantasys    时间: 2011-10-13 11:48

实例才是最容易让人明白且记住的。
作者: awuu    时间: 2011-12-24 16:05

谢谢了,理解是简单
作者: zhouhuang    时间: 2012-1-5 09:28

谢谢高手!!你讲的太好了!!
作者: zpp    时间: 2013-3-22 16:35

顶一下~~~~
作者: 尘丶    时间: 2015-4-25 09:38

虽然之前在别的地方看过了,现在再看,印象更深了。
作者: 437153    时间: 2015-5-15 16:07

通俗易懂,好贴!
作者: ai20110304    时间: 2018-8-29 17:08

都是预处理惹得祸。    记住复合语句时有即时变量访问开启环境变量延迟。
谢谢
作者: gcbgczhang    时间: 2018-9-18 12:48

...每次都忘————赋不上就加setlocal EnableDelayedExpansion和!!
作者: JC_2019    时间: 2019-7-17 10:15

谢谢你的贴子!!!
作者: jrx401    时间: 2019-10-22 07:17

言简意概,占
作者: dzddz    时间: 2020-2-29 21:00

感谢楼主的讲解,简单易懂。




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2