找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 21246|回复: 5

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

[复制链接]
发表于 2012-10-19 18:13:43 | 显示全部楼层 |阅读模式
本帖最后由 极品小猫 于 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
复制代码

评分

参与人数 1PB +2 收起 理由
Batcher + 2 感谢给帖子标题标注[已解决]字样

查看全部评分

发表于 2012-10-19 19:19:19 | 显示全部楼层
  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技术 +1 收起 理由
Batcher + 1 乐于助人

查看全部评分

发表于 2012-10-19 22:31:00 | 显示全部楼层
本帖最后由 随风 于 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技术 +1 收起 理由
Batcher + 1 乐于助人

查看全部评分

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


楼上重出江湖了?
 楼主| 发表于 2012-10-20 00:31:03 | 显示全部楼层
本帖最后由 极品小猫 于 2012-10-20 09:46 编辑
for等复合语句内部提取变量,有2种方法
1、用for中转,最常用的方法,也是目前最高效的方法。
2、call 扩 ...
随风 发表于 2012-10-19 22:31



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

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

说到这也明白了 %%.!M!%% 的结果能够获取二次扩展结果的原因.
%%.!N!%% 已经把 !N! 作为变量名, 结果我又卡壳在 For 里面
发表于 2012-10-20 03:56:09 | 显示全部楼层
1,%1~%9
2,%a%
3,%%i
4,!a!
5,call %%a%%  %的数量是看CALL的,也就是你扩展的次数
其实也有文章说有SET /A的,但是没用过,所以不了解,1——4常用,5就有些说不过去了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-19 15:22 , Processed in 0.020079 second(s), 8 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表