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

[已解决] BAT启用变量延迟后,在For中如何输出变量二次扩展的结果?

本帖最后由 极品小猫 于 2012-10-20 00:31 编辑

不知道标题与文章内容相不相符,求大神指点

该问题算是 http://bbs.bathome.net/thread-18546-1-1.html 的一个延伸
在这个帖子里解决了变量值作为变量名再赋值的问题,详见下面的代码
  1. @echo off
  2. setlocal ENABLEDELAYEDEXPANSION
  3. for /f %%i in ('dir /b /ad') do (
  4.         set /a num+=1
  5.         set !num!=%%i
  6.         echo !num!. %%i
  7. )
  8. echo,
  9. set /p i=请输入要操作的用户目录编号:
  10. echo !%i%!
  11. ENDLOCAL
  12. pause
复制代码
在 For 外,使用 !%i%! 成功显示了 !num! 的赋值,得到了目录名

但是,如果想要在 For 中输出 !num! 的赋值该如何做?

查了很多关于 变量延迟、变量扩展、变量二次扩展、For 的技术帖和资料都没找到方法。

后来看到该帖子:http://bbs.bathome.net/viewthread.php?tid=16154
如果要在For中如果想要输出二次扩展后的值,需要以下条件
1、在变量二次扩展时,变量名前面需要加一个字符(例如:逗号、句号)
2、输出二次扩展时需要用到Call ,方法为:call echo %%.!m!%%

对于 %%.!m!%% 个人理解为:
!m! 是输出 第一次的变量延迟的结果
Call 与两对百分号产生了变量延迟的效果,从而获得了二次扩展后的值

但是让我不理解的是,只有在加入那一个字符后才起作用,这个字符是作为分隔符吗?还是在处理时实际上被忽略掉? 或者实际上就是第二个变量名?

假如加了标点符号的是第二个变量名,那就不算是二次扩展了,但是在输出时的引用方式中,却又夹杂了二次扩展的影子。

我已经被这个问题给搞晕了,无从判断,求大神解救。

以下为测试代码:
  1. @echo off & setlocal enabledelayedexpansion
  2. set num=0
  3. for /f %%i in ('dir /b /ad') do (
  4.         set/a n+=1
  5.         call set ".!n!=%%i"
  6. call echo 当前行为:%%.!n!%%
  7. set/a m=!n!-1
  8. call echo 上一行为:%%.!m!%%
  9. echo,
  10. )
  11. echo,
  12. set /p i=请输入要操作的用户目录编号:
  13. echo !.%i%!
  14. ENDLOCAL
  15. pause
复制代码
1

评分人数

    • Batcher: 感谢给帖子标题标注[已解决]字样PB + 2

  1. @echo off & setlocal enabledelayedexpansion
  2. set num=0
  3. for /f %%i in ('dir /b /ad') do (
  4.         set/a n+=1
  5.         call set "#!n!=%%i"  %设置变量用了#号%
  6.         call echo 当前行为:%%#!n!%% %显示时也用#号%
  7.         set/a m=!n!-1
  8.         call echo 上一行为:%%#!m!%%
  9.         echo,
  10. )
  11. echo,
  12. set /p i=请输入要操作的用户目录编号:
  13. echo !#%i%!
  14. ENDLOCAL
  15. pause
复制代码
所以这个 点( . ) 或者 # 只是变量名的一部分
1

评分人数

如无特别说明,代码测试环境均为 XP SP3

TOP

本帖最后由 随风 于 2012-10-19 22:33 编辑

for等复合语句内部提取变量,有2种方法
1、用for中转,最常用的方法,也是目前最高效的方法。
2、call 扩展延时,非万不得已不要用,严重牺牲效率。
注:因为用%%表示变量存在优先级的问题,所以建议养成不用数字为变量名首字符的习惯,通常用字符或字母作前缀。如:#1、$1、或 a1、h1等等。。。
  1. @echo off
  2. setlocal ENABLEDELAYEDEXPANSION
  3. for /f %%i in ('dir /b /ad') do (
  4.         set /a num+=1
  5.         set #!num!=%%i
  6.         for %%a in (!num!) do echo !#%%a!
  7.         call echo %%#!num!%%
  8.         call call echo %%%%#%%num%%%%%%
  9.         echo,
  10. )
  11. pause
复制代码
1

评分人数

技术问题请到论坛发帖求助!

TOP

for等复合语句内部提取变量,有2种方法
1、用for中转,最常用的方法,也是目前最高效的方法。
2、call 扩 ...
随风 发表于 2012-10-19 22:31


楼上重出江湖了?

TOP

本帖最后由 极品小猫 于 2012-10-20 09:46 编辑
for等复合语句内部提取变量,有2种方法
1、用for中转,最常用的方法,也是目前最高效的方法。
2、call 扩 ...
随风 发表于 2012-10-19 22:31



感谢随风老大的回复
一般都直接开启变量延迟扩展, 所以很少用到 Call, 也在论坛内看了很多关于Call的变量延迟的使用和一些弊端, 感觉实在太过复杂了, 哈哈.

回到正题,  因为是特殊需求所用到的, 所以才以数字作为变量名. %% 优先级问题真是一句惊醒梦中人.

说到这也明白了 %%.!M!%% 的结果能够获取二次扩展结果的原因.
%%.!N!%% 已经把 !N! 作为变量名, 结果我又卡壳在 For 里面

TOP

1,%1~%9
2,%a%
3,%%i
4,!a!
5,call %%a%%  %的数量是看CALL的,也就是你扩展的次数
其实也有文章说有SET /A的,但是没用过,所以不了解,1——4常用,5就有些说不过去了
枫中残雪:风停了,我的心却在动,让我心中的寒意走向远方

TOP

返回列表