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


【选项部分的参数】如何改变一直没方法(对大多数人,但我不敢断言就一直没方法);

【括号里的参数】在循环体内改变,这样的例子 【不胜枚举】;
  1. for %%a in (1 2)do set loop=%%a&for /l %%b in (1 1 !loop!)do echo %%b
  2. Set loop=1 1 2
  3. for %%a in (1 1) do for /L %%b in (!loop!) do Set loop=626 1 627& ECHO %%b
复制代码
你这个C语言代码推测很容易被推翻。

TOP

我原以为,for是以类似%1的形式接受参数的,但是下面这个怪异现象又让我迷茫了:
  1. for /f "delims= "tokens^=2 %%a in ("haha test") do echo %%a
  2. ::正确
  3. for /f tokens^=2"delims= " %%a in ("haha test") do echo %%a
  4. ::出错
复制代码
第一条可以执行,的二条却出错,这就与call的情况不一样了,为什么呢?

TOP

46# plp626

你没理解我的意思:
for /l %a in (start,step,end) do ... //在循环体中再怎么改变start,step,end,已经不影响for的条件了
这里指的是类似这种方式:
set /a start=1, step=1, end=3
for /l %%a in (!start!,!step!,!end!) do ping -n 1 192.168.0.%%a >nul && set /a end+=1
这样是无法改变循环条件的。

既然括号里面的参数可以是变量,当然可以在for之前改变变量值,然后再运行for,也就是你那种情况,但与我说的完全不是同一种类型。

TOP

for 是内部命令,无需那种调用外部程序时带的参数。

如果for是外部命令,那么for %%i do (set x=%%i) 就无法实现,因为FOR如果不是内部命令,就无法更改FOR外部的全局变量。

同时,大多数外部命令,没有打开stdin的,都不接受 ( 多行语句文本 ) 。

而打开stdin的比如findstr,也是在findstr运行之后才打开stdin,无法在传递参数的初始阶段就接受括号 () 包裹的多行文本。

TOP

47# zm900612


for /f "delims= ""tokens=1-3" %a in ("aa bb cc") do echo %a.%b.%c
这样不会报错,但结果是aa.%b.%c,好像tokens=2未起作用。

for /f "eol=a""delims= ""tokens=1-3" %a in ("aa bb cc") do echo %a.%b.%c
这样也没问题,而且eol生效了。

for /f "eol=b""delims= ""tokens=1-3" %a in ("aa bb cc") do echo %a.%b.%c
结果:aa.%b.%c,虽然eol生效了,但后面的不生效。

for /f eol^=a"delims= ""tokens=1-3" %a in ("aa bb cc") do echo %a.%b.%c
出错:此时不应有 "delims= ""tokens=1-3"。

for /f "delims= ""tokens=1-3""eol=a" %a in ("aa bb cc") do echo %a.%b.%c
这样没问题,但eol不生效。

for /f "delims= "tokens^=1-3eol^=a %a in ("aa bb cc") do echo %a.%b.%c
很好,不出错,而且所有选项均生效了。

for /f "usebackq delims= "tokens^=1-3eol^=a %a in ("aa bb cc") do echo %a.%b.%c
“系统找不到文件 aa bb cc。”,但这不是语法错误,而是for已经成功运行了,只不过找不到文件(找不到才正确,本来就没有)

for /f "usebackq""delims= "tokens^=1-3eol^=a %a in ("aa bb cc") do echo %a.%b.%c
也不出错,但除了usebackq外其他选项不生效。

for /f "usebackq"delims^=^ tokens^=1-3eol^=a %a in ("aa bb cc") do echo %a.%b.%c
这个当然没问题啦,都生效。

回到开始:
for /f eol^=a"delims= " %a in ("aa bb cc") do echo %a.%b.%c
出错:此时不应有 "delims= "。

看来跟引号的位置有关系,大致如下:
如果引号出现在所有选项前,则第一对引号中的选项都有效;后面如果还有引号包含选项则其中的选项不生效;如果只有一对引号,引号外面还有选项,则可以生效。
如果在引号出现前已经有选项,则如果把后面的选项用引号包含起来会出语法错误。

TOP

上面的结论好像也不完全对。
for /f "usebackq"delims^=^ tokens^=1-3eol^=a %a in (`echo aa bb cc`) do echo %a.%b.%c
结果:aa.%b.%c
后面的选项没生效。

for /f "usebackqdelims= "tokens^=1-3eol^=b %a in (`echo aa bb cc`) do echo %a.
%b.%c
aa.bb.cc
这个却OK,都生效了。

难道usebackq有点特殊?

TOP

45# powerbat


括号里的参数是for的入口的参数,它改变后,重新调用这个for接口就可被再次读取;
这也就可以说明为什么
  1. set x=0
  2. for %%a in (1 2 !x! !x!)do echo %%a&set x=y
复制代码
不能改变;而
  1. set x=0
  2. for %%z in (1 1)do for %%a in (1 2 !x! !x!)do echo %%a&set x=y
复制代码
却被改变的原因;
=============================================
对于选项部分的参数(不知道该怎么叫,大家理解就好)我也仅是靠现象猜测(仅是便于理解):

选项部分的参数直接和for接口函数功能相关联,但在预处理的时候就被读取固定下来;
只要是在这个预处理阶段读取的语句,不管这个语句怎么改变选项部分的参数
能改变的仅仅是参数的值,而非这个for接口的函数功能了;

TOP

49楼又给了我提示。
为什么只有for、if这两个命令可以引导括号包含的多行语句块?(当然干脆不要任何命令引导,单独使用括号也是语句块)
说明预处理时看到有for、if,对待就不同了,所以for、if肯定是参与了预处理的。
由此看来for、if的确有关键字的特征。

TOP

47# zm900612


for /f "delims= ""tokens=1-3" %a in ("aa bb cc") do echo %a.%b.%c
这样不会报错,但结果是aa.%b.%c,好像tokens=2未起作用。

for /f "eol=a""delims= ""tokens=1-3" %a in ("aa bb cc") ...
powerbat 发表于 2011-5-27 19:22

我晕了,昨天只是想到call参数的特性,试了一下,没研究这么多。
佩服

TOP

52# plp626


for %%z in (1 1)do for %%a in (1 2 !x! !x!)do echo %%a&set x=y
外层的for要展开语句的,里面的语句执行一次后,变量值改变了,这是在第二次for运行之前,当然有效了。
它和把for写成两行没什么本质区别:
for %%a in (1 2 !x! !x!)do echo %%a&set x=y
for %%a in (1 2 !x! !x!)do echo %%a&set x=y

TOP

55# powerbat


是这样:
  1. (
  2. for %%a in (1 2 !x! !x!)do echo %%a&set x=y
  3. for %%a in (1 2 !x! !x!)do echo %%a&set x=y
  4. )
复制代码

TOP

本帖最后由 cjiabing 于 2011-5-28 02:40 编辑

token与delims的困惑:
在以下处理中,在“tokens=* delims=o”一行命令中,已经定义了小写字母“o”为分隔符,为何后面显示出来的时候,还是显示字母“o”?
即使使用“tokens=1,2,* delims=o”,最后几个字母“o”仍然会出现。
在我们的理解中,被定义为分隔符的字符默认是被忽略不显示的,但以上“会显示的分隔符”让人困惑。
类似的问题很多,在定义分隔符提取指定列时,对此往往很无奈。delims或者tokens会消极怠工,不按规定完成任务。
  1. @echo off
  2. for /f "skip=25 usebackq tokens=* delims=echo" %%a in (%0) do echo %%a
  3. echo,
  4. echo, 注意观察最后一行的字母“o”。
  5. echo,
  6. pause
  7. cls
  8. for /f "skip=25 usebackq tokens=* delims=o" %%a in (%0) do echo %%a
  9. echo,
  10. echo, 注意观察最后一行的字母“o”。
  11. echo,
  12. pause
  13. cls
  14. for /f "skip=25 usebackq delims=o" %%a in (%0) do echo %%a
  15. echo,
  16. echo, 注意观察最后一行的字母“o”。
  17. echo,
  18. pause
  19. cls
  20. for /f "skip=25 usebackq tokens=1,2,* delims=o" %%a in (%0) do echo [%%a] [%%b] [%%c]
  21. echo,
  22. echo, 注意观察最后一行的字母“o”。
  23. echo,
  24. pause
  25. exit
  26. echo.&echo.
  27. echo. &set/p=按任意键返回&cls&
  28. echo.使用说明:
  29. c
  30. ch
  31. sssssssss echo eeeeeeeee
  32. ececechechoechoochochco
  33. eceho&echo&echoddls
  34. i love you,i love bathome.
复制代码
寂寞是黑白的,但黑白不是寂寞,是永恒。BAT 需要的不是可能,而是智慧。

TOP

57# cjiabing


tokens=m-n* 的情况下,n之后的字符串不会被分割,这在 for /?中有明确说明。

如果还要分割,那么会破坏字符串,无法得到预期的要求,特别是长字符串的时候,出现预料外的分割的话,无法还原这个字符串了。

TOP

58# caruko
老兄,可为什么我用“tokens=*”的情况下它仍然不显示呢?
寂寞是黑白的,但黑白不是寂寞,是永恒。BAT 需要的不是可能,而是智慧。

TOP

57# cjiabing
兄弟有点丢基础了。。。
***共同提高***

TOP

返回列表