标题: [已解決]批处理中call和set怎样合用? [打印本页]
作者: strong12345 时间: 2009-2-12 12:24 标题: [已解決]批处理中call和set怎样合用?
小弟在之前發的一文中
版主大大們幫我解決了問題,並提供代碼
小弟在之前发的一文中
版主大大们帮我解决了问题,并提供代码
小弟常感谢
不过里面有句 call 和 set 合用的问题
想请教一下
因为小弟觉得这跟原本小弟问的问题性质不太相同,所以另外开了此帖发问
原代码:- @echo off
- for /f "delims=" %%a in ('dir/b') do call set dir_list=%%dir_list%% %%a
- echo %dir_list%
- pause
复制代码
其中- 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 编辑 ]
作者: Batcher 时间: 2009-2-12 12:35
参考《for语句从入门到精通》中关于变量延迟扩展的讲解
http://bbs.bathome.net/thread-2189-1-1.html
作者: batman 时间: 2009-2-12 23:14
这就是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,也就是第二次赋值没有成功,而第二段代码显示出2,显然第二次赋值被确认。这其实也涉及到cmd的预处理
机制,cmd会按由上至下的顺序(有跳转除外)逐行读取和处理程序命令(注意在一个括号内的命令也被视为一行),在上面第一
个代码中set "a=2"&....是被做为一条命令读取的,读取后cmd就会分析变量a在前面是否已被定义,如有就延缓前面的定义,所以显
示为1(前面变量a被定义为1)。而在第二个代码中因为有了call的延迟作用,cmd将会将set "a=2"&这一行两做为两个命令来执行,
所以变量a被定义为2,但记住加入了call后变量符号要由原来的%%改为%%%%。将第一个代码做如下修改也可达到同样效果(开启
变量延迟):
- @echo off&setlocal enabledelayedexpansion
- set "a=1"
- set "a=2"&echo !a!
- pause>nul
复制代码
[ 本帖最后由 batman 于 2009-2-12 23:15 编辑 ]
作者: namejm 时间: 2009-2-12 23:21
“逐行读取”的提法之后,应该再加上“逐条执行”的说法,否则,很容易被顺理成章地误解为逐行执行的,对新手而言,“逐条执行”的概念需要扎根心底,才能更好地理解变量延迟的运作机制。
作者: batman 时间: 2009-2-13 00:28
多谢namejm的指正,确实是如此,是本人未考虑周全了。。。
作者: strong12345 时间: 2009-2-13 18:36
版主大大
小弟改成这样-
- @echo off
- for /f %%a in ('dir /b') do (call set dir_list=%%dir_list%% %%a)
- set dir_list
- pause
复制代码
也能显示所有档案
但是小弟不懂为什么-
- call set dir_list=%%dir_list%% %%a
复制代码
把变数dir_list设为自己 后面又接了一个 %%a ??
小弟目前知道的是∶
dir /b 指令输出 会变成%%a
不知道为什么%%a 又变成 %dir_list%
延迟变量部份已经懂了 谢谢
[ 本帖最后由 strong12345 于 2009-2-13 18:48 编辑 ]
作者: strong12345 时间: 2009-2-13 20:27
小弟刚刚吃饭时,自己想想
终于想通了
刚刚做了个实验
- @echo off
- for /f %%a in ('dir /b') do (call set dir_list=%%dir_list%% %%a&set dir_list&pause)
- pause
复制代码
证实我想的没错
问题已解 ^_^
作者: LWJ菜鸟 时间: 2011-6-27 16:20
这就是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来进行延迟,但是为什么下面这段代码缺少了其中任何一个就不行啊?- @echo off&setlocal enabledelayedexpansion
- set "str=abcdefghijklmnopqrstuvwxyz0123456789"
- set "code=jpg txt bat exe wma mp3"
- md test&cd test
- for /l %%a in (1,1,20) do (
- for /l %%b in (1,1,9) do (
- set /a a=!random!%%36
- call,set "var=!var!%%str:~!a!,1%%"
- )
- set /a b=!random!%%6+1&call :lp
- set "var="
- )
- goto :eof
- :lp
- for /f "tokens=%b%" %%c in ("%code%") do echo.>!var!.%%c
复制代码
作者: 我是马甲 时间: 2011-6-27 16:54
8# LWJ菜鸟
参考 http://bbs.bathome.net/viewthrea ... hlight=%D0%A7%C2%CA
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |