中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
作者:
标题: 整理延迟变量扩展介绍 上一主题 | 下一主题
ywwywwjm
初级用户





积分 42
发帖 13
注册 2007-8-3
状态 离线
『楼 主』:  整理延迟变量扩展介绍

引用变量的值在批处理中习惯叫变量扩展。
使用一对百分号括起变量名(如:%VAR%)的形式表示变量扩展。

延迟引用变量的值叫延迟变量扩展。
使用一对感叹号括起变量名(如:!VAR!)的形式表示延迟变量扩展。
是指变量扩展这个动作被推迟。

有了变量扩展。为什么又多出一个延迟变量扩展呢?

先看下面程序片段1:
set VAR=before
if "%VAR%" == "before" (
   set VAR=after
   echo %VAR%
)
运行结果是什么?
结果是:before
而正确逻辑结果应是:after

为什么会发生这样的事呢?
原来命令解释程序(cmd)在执行复合语句之前做了预处理,即读入复合语
句时做了变量扩展。对于程序片段1,命令解释程序读入if复合语句,接着
做VAR变量扩展,由于此时set VAR=after语句还没有执行,VAR变量的值
未被改变仍然是before,因此,%VAR%扩展为before ,echo %VAR%语句
变为echo before 。然后,命令解释程序从if语句的开头开始执行,很明显
改变VAR变量的值对echo before语句没有影响,执行结果是before 。

扩展后的程序片段1:
set VAR=before
if " before " == "before" (
   set VAR=after
   echo before
)

再看一个程序片段2:(给当前目录文件列表的每行加上序号)
set count=0
for %%i in (*) do (
   set /a count += 1
   echo %count% %%i
)
运行结果:所有序号都是0
不是正确的逻辑结果。

原因与程序片段1一样。命令解释程序读入for复合语句,接着做count变
量扩展,由于此时set /a count += 1语句还没有执行,count变量的值未被改
变仍然是0,因此,%count%扩展为0 ,echo %count% %%i语句变为echo 0
%%i 。然后,命令解释程序从for语句的开头开始执行,很明显改变count
变量的值对echo 0 %%i语句没有影响,执行结果的序号是0 。

扩展后的程序片段2:
set count=0
for %%i in (*) do (
   set /a count += 1
   echo 0 %%i
)

为了解决以上缺陷,命令解释程序增加了在运行时才进行变量扩展的功能
--"延迟变量扩展"。即命令解释程序在读入语句时不做延迟变量扩展,而推
迟到在执行时才做延迟变量扩展。因此,在if、else、for和用"& | && ||"
等连接起来的复合语句中,在变量扩展前变量的值发生了变化,就要将变量
扩展改为延迟变量扩展,令变量扩展在执行时才进行,从而得到变化了的变
量值。

因此,要将以上程序片段中变量扩展改为延迟变量扩展,修改后的程序片段:
set VAR=before
if "!VAR!" == "before" (
   set VAR=after
   echo !VAR!
)

set count=0
for %%i in (*) do (
   set /a count += 1
   echo !count! %%i
)

但是,默认情况下,"延迟变量扩展"功能是停用的。
启用这项功能,有几种方法:
1. 运行cmd /v: on 进入命令提示符窗口,然后输入命令。
2. 直接运行cmd /v: on /c "commands"
3. 在批处理文件里使用这项功能之前设置:setlocal enabledelayedexpansion
4. 设置注册表,让cmd默认情况下启用这项功能,可参考命令:cmd/?

总结以上要点,将程序片段2完善后,得到以下批处理程序—myDir.bat:
:: 给当前目录文件列表的每行加上序号
@echo off
setlocal enabledelayedexpansion

set count=0
for %%i in (*) do (
   set /a count += 1
   echo !count! %%i
)

运行程序,结果正确。

最后,如果不想为何时使用延迟变量扩展而烦恼,可以一开始就使用延迟变量扩展,替代变量扩展。

[ Last edited by ywwywwjm on 2007-8-6 at 11:11 PM ]

2007-8-4 18:10
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
wordexport
初级用户




积分 87
发帖 42
注册 2007-9-27
状态 离线
『第 2 楼』:  

学习了

2007-9-28 16:08
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
batching
新手上路





积分 7
发帖 4
注册 2007-5-7
来自 重庆
状态 离线
『第 3 楼』:  

好东西呀,谢谢了,收藏.

2007-9-28 20:46
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
fenchang2047
新手上路





积分 7
发帖 3
注册 2007-8-20
状态 离线
『第 4 楼』:  

学习了,解决了我那个问题,感谢楼主

2007-9-28 23:50
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
xswdong
中级用户





积分 216
发帖 129
注册 2007-2-14
状态 离线
『第 5 楼』:  


太好了,学习中^

2007-9-30 18:37
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
wjdidi
初级用户





积分 175
发帖 55
注册 2007-4-30
状态 离线
『第 6 楼』:  

是该好好学学啦,,呵,好长时间没看,都忘得差不多了
晚上搞个获取歌曲名,然后自动生成网页播放器播放列表的文件的批处理
搞了将近半个小时,,汗。。。。
总是太疏忽。。。。。
谢谢高手的们的无私奉献

[ Last edited by wjdidi on 2008-1-12 at 02:19 AM ]

2008-1-12 02:18
查看资料  发短消息 网志   编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: