Board logo

标题: 批处理中的for语句小结 [打印本页]

作者: keen    时间: 2009-6-4 22:54     标题: 批处理中的for语句小结

个人自己总结, 参考了英雄的部分资料,很粗糙,有什么不足,大家补正!
  1. for语句总结
  2. 1、for 后面没有任何参数
  3. set str=a b c
  4. set str=a,b,c
  5. set str=a=b=c
  6. set str=a;b;c
  7. for %%i in (%str%) do echo %%i
  8. 四种符号相隔abc: 空格、逗号、等号、分号
  9. 2、for /l
  10. for /l %%i in (1 1 100) do echo %%i
  11. for /l %%i in (100 -1 1) do echo %%i
  12. (1 1 100) (1,1,100) (1;1;100) (1=1=100)
  13. 四种符号相隔1 1 100: 空格、逗号、等号、分号
  14. 3、for /f
  15. for /f ["option"] %%i in (filename) do command
  16. for /f ["option"] %%i in ("string") do command
  17. for /f ["option"] %%i in ('command') do command
  18. option:  eol=c            忽略以c开头的行,默认忽略 ;开头的行
  19.          skip=n           忽略前n行
  20.          delims=xxx       以 每个 x  为分隔符,默认以空格为分隔符
  21.          tokens=x,y,m-n   提取分隔后的第几部分,和delims联合用,默认提取第一部分         
  22.          usebackq         一种特殊用法(见后面)
  23. 当option为usebackq时,用法如下:
  24. for /f "usebackq" %%i in ("filename") do command
  25. for /f "usebackq" %%i in ('string') do command
  26. for /f "usebackq" %%i in (`commamd`) do command
  27. 有人会问,这个参数究竟有什么作用?
  28. 答:当你要解析的文件的路径中带有空格,比如你要解析的文件路径为C:\Documents and Settings\Administrator\桌面\hero.txt。
  29. 如果不用usebackq参数,你将得不到正确的结果。
  30. 如果你这样写的话
  31. @echo off
  32. for /f %%i in ("C:\Documents and Settings\Administrator\桌面\hero.txt") do echo %%i
  33. pause
  34. 结果只是解析了一个字符串而不是文件。
  35. 如果你这样写的话
  36. @echo off
  37. for /f %%i in (C:\Documents and Settings\Administrator\桌面\hero.txt) do echo %%i
  38. pause
  39. 结果会提示找不到C:\Documents。
  40. 而如果这样写
  41. @echo off
  42. for /f "usebackq" %%i in ("C:\Documents and Settings\Administrator\桌面\hero.txt") do echo %%i
  43. pause
  44. 你就可以得到正确的结果。
  45. 4、for /r
  46. for命令中的“/r”参数是个比较有用的参数,下面将具体讲解。
  47. 基本格式:FOR /r 路径 %%variable in (set) do something
  48. 检查以“路径”为根的目录树。如果在 /r 后没有指定目录,则使用当前目录。
  49. 如果集(set)为一个单点(.)字符,则枚举该目录树。
  50. 例1:
  51. 显示出c盘下所有的txt文件。
  52. @echo off
  53. for /r c:\ %%i in (*.txt) do echo %%i
  54. pause
  55. 例2:
  56. 枚举当前目录下的所有子目录及子目录的目录……
  57. @echo off
  58. for /r  %%i in (.) do echo %%i
  59. pause
  60. 不过在所得的目录后面都会带一个“.”。
  61. 例3:
  62. 在当前目录的父目录中寻找txt文件。
  63. @echo off
  64. for /r .. %%i in (*.txt) do echo %%i
  65. pause
  66. 解说:本例中的“..”代表当前目录的父目录。
  67. 例4:
  68. 在论坛中常有人这样写
  69. @echo off
  70. for /r . %%i in (*.txt) do echo %%i
  71. pause
  72. 这里的“.”可以去掉,表示的是当前目录。
  73. “/r”参数还有一些地方需要我们注意--集(set)中的元素会被识别为字符串而
  74. 非文件名除非有通配符修饰。
  75. 例5:
  76. @echo off
  77. for /r %%i in (hero.txt) do echo %%i
  78. pause
  79. 这里的hero.txt不会被识别为文件名,而仅仅被识别为字符串。如果你想在指定
  80. 的目录中搜索文件hero.txt,请看下两个例子。
  81. 例6:
  82. @echo off
  83. for /r %%i in (*hero.txt) do echo %%i
  84. pause
  85. 本例中由于有通配符“*”,故“*hero.txt”被识别为文件名。
  86. 例7:
  87. @echo off
  88. for /r %%i in (hero.txt) do if exist %%i echo %%i
  89. pause
  90. 这样我们就可以找到真正存在的hero.txt文件了。
  91. 5、for /d
  92. 基本格式:FOR /d %%variable in (set) do something
  93. 如果集(set)中包含通配符,则识别为目录名,否则将被识别为字符串。
  94. 作用是--遍历当前目录下(set)中所指定的目录。
  95. 例1:
  96. @echo off
  97. for /d %%i in (hero) do echo %%i
  98. pause
  99. 本例中由于集(hero)中不含有通配符,故“hero”仅仅被识别为字符串。
  100. 例2:
  101. @echo off
  102. for /d %%i in (*hero) do echo %%i
  103. pause
  104. 本例中由于集(*hero)中含有通配符*,故“*hero”被识别为文件名,结果
  105. 遍历了当前目录下所有与*hero匹配的目录。
  106. 6、FOR 变量参照的替换已被增强。您现在可以使用下列选项语法:
  107.    
  108.      ~I         - 删除任何引号("),扩充 %%I
  109.      %%~fI        - 将 %%I 扩充到一个完全合格的路径名
  110.      %%~dI        - 仅将 %%I 扩充到一个驱动器号
  111.      %%~pI        - 仅将 %%I 扩充到一个路径
  112.      %%~nI        - 仅将 %%I 扩充到一个文件名
  113.      %%~xI        - 仅将 %%I 扩充到一个文件扩展名
  114.      %%~sI        - 扩充的路径只含有短名
  115.      %%~aI        - 将 %%I 扩充到文件的文件属性
  116.      %%~tI        - 将 %%I 扩充到文件的日期/时间
  117.      %%~zI        - 将 %%I 扩充到文件的大小
  118.      %%~$PATH:I   - 查找列在路径环境变量的目录,并将 %%I 扩充
  119.                    到找到的第一个完全合格的名称。如果环境变量名
  120.                    未被定义,或者没有找到文件,此组合键会扩充到
  121.                    空字符串
  122. 可以组合修饰符来得到多重结果:
  123.      %%~dpI       - 仅将 %%I 扩充到一个驱动器号和路径
  124.      %%~nxI       - 仅将 %%I 扩充到一个文件名和扩展名
  125.      %%~fsI       - 仅将 %%I 扩充到一个带有短名的完整路径名
  126.      %%~dp$PATH:i - 查找列在路径环境变量的目录,并将 %%I 扩充
  127.                    到找到的第一个驱动器号和路径。
  128.      %%~ftzaI     - 将 %%I 扩充到类似输出线路的 DIR
  129. 这里只给出一个例子,具体的读者可以在实际应用中细细体会。
  130. 例:
  131. @echo off
  132. for /r %%i in (*.txt) do echo %%~zi    %%~ni
  133. pause
  134. 结果:显示当前目录及其子目录下的所有txt文档,左半部分显示文件的大小,右半部分是文件名(不包含扩展名)。
  135. 解说:“%%~zi”代表文件的大小,“%%~ni”代表文件名(不包含扩展名)。
  136.        加上~,去掉双引号
  137.        f:全路径
  138.        d:盘符(d:driver)
  139.        p:相对路径
  140.        n:名字(n:name)
  141.        x:扩展名(x:extension)
  142.        s:全路径的短名,例如:C:\DOCUME~1\ADMINI~1\
  143.        a:文件属性,(a:attrib)
  144.        t:文件的日期、时间(t:date、time)
  145.        z:文件大小(z:size)
  146. 例:
  147. @echo off
  148. echo %0
  149. echo %~0
  150. echo %~f0
  151. echo %~d0
  152. echo %~p0
  153. echo %~n0
  154. echo %~x0
  155. echo %~s0
  156. echo %~a0
  157. echo %~t0
  158. echo %~z0
  159. echo %~dp0
  160. echo %~nx0
  161. echo %~fs0
  162. pause
复制代码

[ 本帖最后由 keen 于 2009-7-10 19:45 编辑 ]
作者: flyzr    时间: 2009-6-4 23:00

很清晰!~
謝謝!


  1. ...
  2. delims=xxx       以 xxx 为分隔符,默认以空格为分隔符
  3. ...
复制代码


貌似xxx不能為字符串,對不對???

[ 本帖最后由 flyzr 于 2009-6-4 23:08 编辑 ]
作者: 随风    时间: 2009-6-4 23:03

很认真的笔记啊,加分!
delims=xxx 需注意是以每个 x 为分隔符,而不是 xxx 字符串

[ 本帖最后由 随风 于 2009-6-4 23:04 编辑 ]
作者: keen    时间: 2009-6-4 23:14     标题: 回复 3楼 的帖子

谢谢版主指正,已修正在顶楼!
作者: tireless    时间: 2009-6-4 23:24

例7:
@echo off
for /r %%i in (hero.txt) do (
if exist %%i echo %%i
)
pause
这样我们就可以找到真正存在的hero.txt文件了。

建议这样:
  1. @echo off
  2. for /r %%i in (hero.txt?) do (
  3.   if /i "%%~nxi"=="hero.txt" echo %%i
  4. )
  5. pause
复制代码

[ 本帖最后由 tireless 于 2009-6-4 23:26 编辑 ]
作者: zqz0012005    时间: 2009-6-4 23:30

不错的总结。

对某几点做一些补充:
1、空格、逗号、等号、分号,这些分隔符并不是for专用的,大多数命令都支持。在DOS时代,空格、等号、分号这3个是默认的分隔符,它们的作用是等价的。CMD下也几乎所以命令都可以用这3个作分隔符。当然不同的命令支持的分隔符也有不同。比如echo还可以用“./\[]”等等。

2、for、for /r 其实并不枚举文件,它们的循环对象就是字符串,除了一个例外:循环集含有通配符*、?。
for %%a in (*) do echo %%a
这个时候你没办法将*、?当作普通字符,加^转义也不行。
for /r 的循环方式是对每个目录执行一次,在循环集里的字符串前面加上目录名。
类似于for /l 的循环方式是对每个数执行一次。

3、for /d 要想循环对象为目录,必须使用通配符,否则与不要选项的单独for作用一样。
作者: keen    时间: 2009-6-4 23:36

回复5 、6楼

谢谢补正!
作者: keen    时间: 2009-7-10 19:30

TO ALL:
  首先,向所有人道个歉。道歉的原因是顶楼的一段话语有误,有误之处看下面:
  1. 5、for /d
  2. 基本格式:FOR /d %%variable in (set) do something
  3. 如果集(set)中包含通配符,则识别为目录名,否则将被识别为字符串。
  4. 作用是--遍历当前目录下(set)中所指定的目录。
  5. 例1:
  6. @echo off
  7. for /d c:\ %%i in (hero) do echo %%i
  8. pause
  9. 本例中由于集(hero)中不含有通配符,故“hero”仅仅被识别为字符串。
  10. 例2:
  11. @echo off
  12. for /d c:\ %%i in (*hero) do echo %%i
  13. pause
  14. 本例中由于集(*hero)中含有通配符*,故“*hero”被识别为文件名,结果
  15. 遍历了当前目录下所有与*hero匹配的目录。
复制代码
当时写这个总结的时候,其它的知识都是自己有所接触,而偏偏这个for /d参数很少用到,为了for语句的完整,当初就把 英雄 的教程中这段直接应用,而没有自己斟酌。

今天在 非常批处理论坛 无意间翻到 英雄 对自己的教程中两处严重错误的更正说明,才是我惊吓一身冷汗,赶紧回来补充这个说明。具体可以参考http://bbs.verybat.org/viewthread.php?tid=14867&highlight=for 八楼 英雄的说明。

正确的for /d参数应该不加路径,正确的应该是这样的:
  1. 5、for /d
  2. 基本格式:FOR /d %%variable in (set) do something
  3. 如果集(set)中包含通配符,则识别为目录名,否则将被识别为字符串。
  4. 作用是--遍历当前目录下(set)中所指定的目录。
  5. 例1:
  6. @echo off
  7. for /d %%i in (hero) do echo %%i
  8. pause
  9. 本例中由于集(hero)中不含有通配符,故“hero”仅仅被识别为字符串。
  10. 例2:
  11. @echo off
  12. for /d %%i in (*hero) do echo %%i
  13. pause
  14. 本例中由于集(*hero)中含有通配符*,故“*hero”被识别为文件名,结果
  15. 遍历了当前目录下所有与*hero匹配的目录。
复制代码
主要错误就是其中的例子,加上了路径。
作者: keen    时间: 2009-7-10 19:38

这个错误发现,是我对for /d参数也产生了疑问,它的用处到底是什么?

for /d参数的使用不能加路径,那么要使用它,就必须把批处理放到相应的路径中,这样就会很麻烦。

请高手赐教!
作者: sy78wpl    时间: 2010-12-23 15:08

3、for /f
for /f ["option"] %%i in (filename) do command
for /f ["option"] %%i in ("string") do command
for /f ["option"] %%i in ('command') do command
option:  eol=c            忽略以c开头的行,默认忽略 ;开头的行
         skip=n           忽略前n行
         delims=xxx       以 每个 x  为分隔符,默认以空格为分隔符
         tokens=x,y,m-n   提取分隔后的第几部分,和delims联合用,默认提取第一部分         
         usebackq         一种特殊用法(见后面)
我想问的是“ eol=c”,只能忽略一个字母吗?
比如我想忽略f、i开头的,可以实现吗?
或者我想忽略以“fi”开头的呢?




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2