标题: 关于for语句的疑惑!!
[打印本页]
作者: stornager
时间: 2007-6-4 20:41
标题: 关于for语句的疑惑!!
a.bat:
@echo off&setlocal EnableDelayedExpansion&color 1f
set %%a=
for /f "usebackq delims=" %%a in (`type a.txt`) do (
set %%a=!%%a:1=!
echo !%%a!
)
pause>nul
______________________________________________
aa.bat:
@echo off&setlocal EnableDelayedExpansion&color 1f
set %%a=0
for /f "usebackq delims=" %%a in (`type a.txt`) do (
set %%a=!%%a:1=!!
echo !%%a!
)
pause>nul
______________________________________________
@echo off
setlcal EnableDelayedExpansion
set %%a=111
set %%a=!%%a:111=!
echo !%%a!
pause
偶没有电脑,没有及时修正这个贴子的错误,实感抱歉!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
本人实在郁闷,很久没用变量延迟竟把setlocal EnableDelayedExpansion和setlocal
extension,setlocal enabledelayedexpansion等同.所以运行时会产生bug.
上面的代码已修正!!!但是有发现了一个新问题,如上面a.txt的内容为:
1234
1345
1456
1567
我想运行上面的a.bat得到aa.txt的内容为:
234
345
456
567
然尔运行的结果却为"1=",我实在想不通!!!!,就算我的方法不对运行的结果也不致这样.?????????????????????????
还有一个关于for的问题,下面的for语句运行的结果为何都是1567??尤其是第四个for语句.
for /f "delims=" %a in (a.txt) do echo %a>aa.txt
for /f "eol= delims=" %a in (a.txt) do echo %a>aa.txt
for /f "eol=" %a in (a.txt) do echo %a>aa.txt
for /f "usebackq eol=" %a in (`type a.txt`) do echo %a>aa.txt
a.txt的内容同上
请高手指点!!
[
Last edited by stornager on 2007-6-6 at 06:49 PM ]
作者: lxmxn
时间: 2007-6-4 22:24
什么bug?
作者: zh159
时间: 2007-6-4 22:27
%%a=!%%a:~111=!
什么东西?获取字符段?替换字符?
作者: dikex
时间: 2007-6-4 22:52
使用了!变量!,但是不用setlocal ENABLEDELAYEDEXPANSION,却使用setlocal enableextensions
不明白楼主在干什么……
作者: lxmxn
时间: 2007-6-6 20:06
Re stornager:
设置变量的时候,最好是不要用%%a等作为变量名,尤其是你的 for 命令中的变量为 %%a 的时候,这样很容易得不到自己想要的结果。
另外,你后来提出的几个问题,就是 > 这个重定向符的问题,因为每次重定向都会先清空文件中的内容然后再把字符添加到文件中,所以你得到的结果只有 “1567” ,如果换成 >> 就可以得到你想要的了。
作者: bjsh
时间: 2007-6-6 20:54
对于这种情况
是和cmd 的预处理机制有关的;
在执行 for 之前;
(即
for /f "usebackq delims=" %%a in (`type a.txt`) do (
set %%a=!%%a:1=!
echo !%%a!
)
)
在执行for之前 会对 for 内部的环境变量 进行替换;
对 %% 包围的 环境变量进行替换;
因为有了 !%%a:1=! 的感叹号 的变量延迟的作用;
他的机制是 执行到当前语句时 再对环境变量进行替换;
但是你的例子的特殊性使得没有得到你的效果;
这是因为 在for 执行的过程中;
当取得 %%a 时 就会对 for 内部的 所有 %%a 进行替换;
当执行 到
set %%a=!%%a:1=!
echo !%%a!
时 %%a 已不再是变量 而被替换为 %%a 所对应的常量;
例如
当第一次循环时;
%%a 取得值1234
for 会将 内部所有的 %%a 进行替换;
当执行到 set %%a=!%%a:1=!
和 echo !%%a!
时实际执行的是
set 1234=!1234:1=!
echo !1234!
因为之前 1234 这个 并不是 个环境变量 因此 !1234:1=! 的结果 并不是 234;
(对于替换字符要求这种格式 : %环境变量:欲替换的字符=替换字符% 或 对应的 !! )
在 词句中 set 1234=!1234:1=! 把 1234 定义成了环境变量;
由于 !1234:1=! 中的 1234 不是 环境变量的原因 因此被替换为空
1234 做为环境变量 由此 被 赋值为 1=;
其余类似 由此得到了你的哪种现象;
你可以体会下面这个例子:
Quote: |
@echo off&
setlocal EnableDelayedExpansion
set 1234=198654
set %%a=
for /f "usebackq delims=" %%a in (`type a.txt`) do (
set %%a=!%%a:1=!
echo !%%a!
)
pause>nul |
|
结果
所以你的代码 实质上 相当于 从 a.txt 中 取出 每一行;
并把这一行 set 成一个 环境变量 ;
这一变量的值 为 1=;
然后 再 echo 这个环境变量;
对于aa.bat
你的
set %%a=!%%a:1=!!
最后一个!是没有作用的;
这是变量延迟的一个特性;说起来很复杂;
还是由于上面分析的原因 ; 得到相同的结果;
其实无论你 把 %%a 定义为何值;
最后的结果是一样的;
因为后面根本就没有用到;
好好理解 for 在程序中的运行过程;
至于对 dos 的脚本要学会自己调试:
可参考
http://www.cn-dos.net/forum/view ... =%E8%B0%83%E8%AF%95
至于你最后一个例子;
因为没有涉及到上面所提到的情况;
正常理解即可;
Quote: |
还有一个关于for的问题,下面的for语句运行的结果为何都是1567??尤其是第四个for语句.
for /f "delims=" %a in (a.txt) do echo %a>aa.txt
for /f "eol= delims=" %a in (a.txt) do echo %a>aa.txt
for /f "eol=" %a in (a.txt) do echo %a>aa.txt
for /f "usebackq eol=" %a in (`type a.txt`) do echo %a>aa.txt |
|
这四个的原因 都是因为 >aa.txt 而不是 >>aa.txt;
因此只保留了最后的结果;
ps: 这是个复杂的问题;
更多请参考
http://www.cn-dos.net/forum/view ... ge=1&highlight=
其实这篇文章并不全面;还有一些问题没有讨论到;
私下里和lxmxn讨论过;得到许多其他有价值的东西;
因为聊天记录过于庞杂 不知该怎么整理;
只能待时间充裕时 再做补充了.
作者: stornager
时间: 2007-6-6 20:58
哦,原来如此,谢谢啦!!