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

[已解決]批处理中call和set怎样合用?

小弟在之前發的一文中
版主大大們幫我解決了問題,並提供代碼
小弟在之前发的一文中
版主大大们帮我解决了问题,并提供代码
小弟常感谢

不过里面有句 call 和 set 合用的问题
想请教一下

因为小弟觉得这跟原本小弟问的问题性质不太相同,所以另外开了此帖发问

原代码:
  1. @echo off
  2. for /f "delims=" %%a in ('dir/b') do call set dir_list=%%dir_list%% %%a
  3. echo %dir_list%
  4. pause
复制代码
其中
  1. for /f "delims=" %%a in ('dir/b') do call set dir_list=%%dir_list%% %%a
复制代码
小弟并不是很理解
为什么可以这样使用指令?

set dir_list=%%dir_list%%  →为什么使用 %% 而不是 % ?
后面的 %%a 应该是 %1 的意思吧?
请问为什么这么做 可以把 %%a 的变数,一直加到 %dir_list%里?

小弟知道 set 和 call 的用法
不过2个 合在一起 这样使用 实在不太懂   @@a"
能不能请哪位大大
说明一下 这指令的流程?

[ 本帖最后由 strong12345 于 2009-2-13 20:29 编辑 ]

参考《for语句从入门到精通》中关于变量延迟扩展的讲解
http://bbs.bathome.net/thread-2189-1-1.html
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

这就是call的延迟用法,楼主可比较下下面两段代码:
  1. @echo off
  2. set "a=1"
  3. set "a=2"&echo %a%
  4. pause>nul
复制代码
  1. @echo off
  2. set "a=1"
  3. set "a=2"&call,echo %%a%%
  4. pause>nul
复制代码
第一段代码显示出1,也就是第二次赋值没有成功,而第二段代码显示出2,显然第二次赋值被确认。这其实也涉及到cmd的预处理
机制,cmd会按由上至下的顺序(有跳转除外)逐行读取和处理程序命令(注意在一个括号内的命令也被视为一行),在上面第一
个代码中set "a=2"&....是被做为一条命令读取的,读取后cmd就会分析变量a在前面是否已被定义,如有就延缓前面的定义,所以显
示为1(前面变量a被定义为1)。而在第二个代码中因为有了call的延迟作用,cmd将会将set "a=2"&这一行两做为两个命令来执行,
所以变量a被定义为2,但记住加入了call后变量符号要由原来的%%改为%%%%。将第一个代码做如下修改也可达到同样效果(开启
变量延迟):
  1. @echo off&setlocal enabledelayedexpansion
  2. set "a=1"
  3. set "a=2"&echo !a!
  4. pause>nul
复制代码

[ 本帖最后由 batman 于 2009-2-12 23:15 编辑 ]
***共同提高***

TOP

  “逐行读取”的提法之后,应该再加上“逐条执行”的说法,否则,很容易被顺理成章地误解为逐行执行的,对新手而言,“逐条执行”的概念需要扎根心底,才能更好地理解变量延迟的运作机制。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

多谢namejm的指正,确实是如此,是本人未考虑周全了。。。
***共同提高***

TOP

版主大大
小弟改成这样
  1. @echo off
  2. for /f %%a in ('dir /b') do (call set dir_list=%%dir_list%% %%a)
  3. set dir_list
  4. pause
复制代码
也能显示所有档案
但是小弟不懂为什么
  1. call set dir_list=%%dir_list%% %%a
复制代码
把变数dir_list设为自己  后面又接了一个 %%a ??

小弟目前知道的是∶
dir /b 指令输出  会变成%%a
不知道为什么%%a 又变成 %dir_list%

延迟变量部份已经懂了 谢谢

[ 本帖最后由 strong12345 于 2009-2-13 18:48 编辑 ]

TOP

小弟刚刚吃饭时,自己想想
终于想通了
刚刚做了个实验
  1. @echo off
  2. for /f %%a in ('dir /b') do (call set dir_list=%%dir_list%% %%a&set dir_list&pause)
  3. pause
复制代码

证实我想的没错

问题已解 ^_^

TOP

这就是call的延迟用法,楼主可比较下下面两段代码:@echo off
set "a=1"
set "a=2"&echo %a%
pause>nul@echo off
set "a=1"
set "a=2"&call,echo %%a%%
pause>nul第一段代码显示出1,也就是第二次赋值没有成功 ...
batman 发表于 2009-2-12 23:14

请问bathman:
按照你的说明,如果有setlocal enabledelayedexpansion就不用CALL来进行延迟,但是为什么下面这段代码缺少了其中任何一个就不行啊?
  1. @echo off&setlocal enabledelayedexpansion
  2. set "str=abcdefghijklmnopqrstuvwxyz0123456789"
  3. set "code=jpg txt bat exe wma mp3"
  4. md test&cd test
  5. for /l %%a in (1,1,20) do (
  6.     for /l %%b in (1,1,9) do (
  7.           set /a a=!random!%%36
  8.           call,set "var=!var!%%str:~!a!,1%%"
  9.      )
  10.     set /a b=!random!%%6+1&call :lp
  11.     set "var="
  12. )
  13. goto :eof
  14. :lp
  15. for /f "tokens=%b%" %%c in ("%code%") do echo.>!var!.%%c
复制代码

TOP

隐藏秘密最好的方法是把秘密当笑话说给所有人听。

TOP

返回列表