标题: 启用延迟变量的一些问题,请大家帮忙解答一下!
[打印本页]
作者: shtcool
时间: 2007-12-26 16:04
标题: 启用延迟变量的一些问题,请大家帮忙解答一下!
大家都知道如果在脚本行首启用延迟变量(setlocal EnableDelayedExpansion)那么会把文本中所有的感叹号抛弃,解决办法用call也不尽人意!
例如1:
set num=0
setlocal enabledelayedexpansion
for /f "delims=" %%i in ('findstr /n .* a.txt') do (
set /a num+=1
set "str=%%i"
echo 第 !num! 行: !str:*:=!
)
pause
文本内容为:
;;;ef &
;:;
::;;
&
^
!<
!
%
"
""
'
""
""
""
""
""
!
但看了以前namejma版主的一段代码,如下2:
set num=0
for /f "delims=" %%i in ('findstr /n .* a.txt') do (
set /a num+=1
set "str=%%i"
setlocal enabledelayedexpansion
echo 第 !num! 行: !str:*:=!
endlocal
)
pause
这段是在for语句内部调用延迟变量能完全兼容感叹号、连接符号、重定向符号、行首分号、行首冒号.
问题就是:为什么在FOR语句内调用延迟变量,延迟变量不会抛弃"!"号?难道是跟延迟变量预处理环境的位置有关?在例1中先执行的延迟变量环境所以会抛弃所有"!"号,在例2中变量str赋值后在执行延迟变量为什么就不抛弃"!"号?何解?请大家告知其中原因,谢谢!
作者: lxmxn
时间: 2007-12-26 16:21
Quote: |
set num=0
setlocal enabledelayedexpansion
for /f "delims=" %%i in ('findstr /n .* a.txt') do (
set /a num+=1
set "str=%%i"
echo 第 !num! 行: !str:*:=!
)
pause |
|
第一个例子中,SetLocal语句写在了for语句的外面,变量延迟作用的范围是这条语句下面所有的语句(这里是for语句),而第二个例子中,SetLocal 命令作用的范围只是上面红色部分的语句,即对另外的两条set语句并没有作用,也就是说,文本中包含“!”字符的话,不会被Setlocal 的作用而影响(也可以理解为扩展),所以第二个例子中,本文的“!”符号不会被Setlocal语句外面的set命令所影响。
这里也涉及到了cmd对命令的预处理机制,简单的说,就是对于没有条批处理语句,cmd在解释运行它之前,都会对它里面变量及参数做必要的扩展动作,比如“echo %str%”,会先把其中的%str%扩展为str变量所对应的值,再来执行这条echo命令,即执行的是“echo <str变量的值>”。
详细的分析可以搜索一下前版主willsort以前写的分析贴。
[
Last edited by lxmxn on 2007-12-26 at 04:23 PM ]
作者: shtcool
时间: 2007-12-26 16:40
感谢版主的解答,以前没有好好的体会,现在真的要好好体会一下了,非常感谢!
作者: nhhulie
时间: 2007-12-31 01:20
这个有点难哦。。