[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
回复 9# shelluserwlb


   
开启变量延时后,只会对!!之间变量进行实时取值,for的用法有点特殊,有点类似于执行到FOR这里,就会根据条件立马初始化分配空间,后面只是单纯执行,而DO后方的语句,都会被以语句块的形式解释,所以对FOR循环内进行实时取值都需要开启延时变量,要么就用CALL,这里%ok:~%%i,1%按说是一个无效变量,但回显开启发现它直接将其初始化成了ok的值,导致行行了几次!abcd!,无此变量,故显示ECHO状态,有点莫名其妙。

TOP

楼主第一个批处理其实用不着开启变量延时。下方的取值操作位于非语句块内,s值已可被正常读取,直接用call echo %%%s:~1,1%%%即可。
第二个批处理中call还是对%%ok%%进行了处理,变成%ok%,第二次是以%ok%作为变量名来进行取值的,由于当前环境找不到此变量名,导致了异常结果的显示。
可以用下方代码进行验证:
  1. @echo on
  2. set ok=adsl
  3. set %%ok%%=lsda
  4. setlocal enabledelayedexpansion
  5. call echo !%%ok%%:~1,1!
  6. endlocal
  7. pause
复制代码

TOP

另外,通过我的实验,这里的call不是必须的,代码第6行修改为echo !%s:~1,1%!
同样可以输出b的值
花了好几个 ...
bgst 发表于 2013-7-23 16:15


    如果去掉call 双百分号在for循环体内好像不行。
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. set ok=abcd
  4. set a=aaaaa & set b=bbbbb & set c=ccccc & set d=ddddd
  5. for /l %%i in (0,1,3) do call echo %%!ok:~%%i,1!%%
  6. endlocal
  7. pause>nul
复制代码
如果把上面第5行中的"call echo %%!ok:~%%i,1!%%" 换成
“echo !%ok:~%%i,1%!” 在执行时就会出错。

TOP

回复 7# mingdedream


    这种用法投机取巧了,执行效率低。
寂寞是黑白的,但黑白不是寂寞,是永恒。BAT 需要的不是可能,而是智慧。

TOP

实际上
call echo !%%ok%%:~1,1!  
这个语句中由于call 的存在会执行两次
第一次:执行过程 echo !%ok%:~1,1!(会脱去OK的百分号)
第二次:执行过程 echo  !adsl:~1,1!
所以最终得出结果~1,1

TOP

谢谢楼主分享,又长知识了...

TOP

另外,通过我的实验,这里的call不是必须的,代码第6行修改为echo !%s:~1,1%!
同样可以输出b的值
花了好几个小时才看明白,还有延缓环境变量没有搞懂

充分说明了楼主大材,希望能够亲自献身解说一下

TOP

开始也看不懂,查了一下才大致明白,写出来供大家参考和补充
    @echo off
    set ok=adsl
    set s=abc
    set b=qdj!ok!
    setlocal enabledelayedexpansion
    call echo %%!s:~1,1!%%
    endlocal

    pause
前4行很简单,第5行和第7行是一起的,启用延缓环境变量,什么意思暂时还没闹明白,关键是第6行
这行整个的意思是显示以环境变量s的第二个字符为名字的环境变量b的值,qdj!ok!
首先看!!,当启用变量延迟时,!!将变量名扩起来表示对变量值的引用
%s:~1,1%表示提取环境变量s第1个字符后面的1字符,这里是b(注意不是第一个字符,如果要选第一个字符应写成%s:~0,1%)
那么%!s:~1,1!%,就变成了%b%,echo %%!s:~1,1!%%就变成了echo %%b%%,所以结果是输出b的值qdj!ok!

TOP

不明觉厉

TOP

不太明白啊

TOP

返回列表