分享

DOS循环for命令详解

 leexingyuan5 2012-12-11

DOS批处理高级教程:第二章 DOS循环for命令详解

[复制链接]

99

主题

9

好友

1221

积分

大家网大学二年级

Rank: 15Rank: 15Rank: 15

积分
1221
帖子
364
精华
18
经验
671 点
威望
24 点
金币
440
发表于 2010-3-10 17:54 |显示全部楼层
DOS批处理高级教程:第二章 DOS循环for命令详解

讲FOR之前呢,咋先告诉各位新手朋友,如果你有什么命令不懂,直接在CMD下面输入:

name /? 这样的格式来看系统给出的帮助文件,比如for /? 就会把FOR命令的帮助全部显示出来!当然许多菜鸟都看不懂....所以才会有那么多批处理文章!!!!俺也照顾菜鸟,把FOR命令用我自己的方式说明下!

正式开始:

一、基本格式

FOR %%variable IN (set) DO command [command-parameters]

  %%variable  指定一个单一字母表示可替换的参数。
  (set)      指定一个或一组文件。可以使用通配符。
  command    指定对每个文件执行的命令。
  command-parameters 为特定命令指定参数或命令行开关。

参数:FOR有4个参数 /d   /l   /r   /f   他们的作用我在下面用例子解释
现在开始讲每个参数的意思

二、参数 /d

FOR /D %%variable IN (set) DO command [command-parameters]

如果集中包含通配符,则指定与目录名匹配,而不与文件名匹配。

如果 Set (也就是我上面写的 "相关文件或命令") 包含通配符(* 和 ?),将对与 Set 相匹配的每个目录(而不是指定目录中的文件组)执行指定的 Command。

这个参数主要用于目录搜索,不会搜索文件,看这样的例子
  1. @echo off
  2. for /d %%i in (c:\*) do echo %%i
  3. pause
复制代码
运行会把C盘根目录下的全部目录名字打印出来,而文件名字一个也不显示!

在来一个,比如我们要把当前路径下文件夹的名字只有1-3个字母的打出来
  1. @echo off
  2. for /d %%i in (???) do echo %%i
  3. pause
复制代码
这样的话如果你当前目录下有目录名字只有1-3个字母的,就会显示出来,没有就不显示了

这里解释下*号和?号的作用,*号表示任意N个字符,而?号只表示任意一个字符

知道作用了,给大家个思考题目!
  1. @echo off
  2. for /d %%i in (window?) do echo %%i
  3. pause
复制代码
保存到C盘下执行,会显示什么呢?自己看吧! 显示:windows
/D参数只能显示当前目录下的目录名字,这个大家要注意!

三、参数 /R

FOR /R [[drive:]path] %%variable IN (set) DO command [command-parameters]

检查以 [drive:]path 为根的目录树,指向每个目录中的FOR 语句。如果在 /R 后没有指定目录,则使用当前目录。如果集仅为一个单点(.)字符,则枚举该目录树。


递归

上面我们知道,/D只能显示当前路径下的目录名字,那么现在这个/R也是和目录有关,他能干嘛呢?放心他比/D强大多了!
他可以把当前或者你指定路径下的文件名字全部读取,注意是文件名字,有什么用看例子!

请注意2点:
  • set中的文件名如果含有通配符(?或*),则列举/R参数指定的目录及其下面的所用子目录中与set相符合的所有文件,无相符文件的目录则不列举。
  • 相反,如果set中为具体文件名,不含通配符,则枚举该目录树(即列举该目录及其下面的所有子目录),而不管set中的指定文件是否存在。这与前面所说的单点(.)枚举目录树是一个道理,单点代表当前目录,也可视为一个文件。

例:
  1. @echo off
  2. for /r c:\ %%i in (*.exe) do echo %%i
  3. pause
复制代码
咱们把这个BAT保存到D盘随便哪里然后执行,我会就会看到,他把C盘根目录,和每个目录的子目录下面全部的EXE文件都列出来了!!!!

例:
  1. @echo off
  2. for /r %%i in (*.exe) do @echo %%i
  3. pause
复制代码
参数不一样了吧!这个命令前面没加那个C:\也就是搜索路径,这样他就会以当前目录为搜索路径,比如你这个BAT你把他放在d:\test目录下执行,那么他就会把D:\test目录和他下面的子目录的全部EXE文件列出来!!!

例:
  1. @echo off
  2. for /r c:\ %%i in (boot.ini) do echo %%i
  3. pause
复制代码
运行本例发现枚举了c盘所有目录,为了只列举boot.ini存在的目录,可改成下面这样:
  1. @echo off
  2. for /r c:\ %%i in (boot.ini) do if exist %%i echo %%i
  3. pause
复制代码
用这条命令搜索文件真不错。。。。。。

这个参数大家应该理解了吧!还是满好玩的命令!

四、参数 /L

FOR /L %%variable IN (start,step,end) DO command [command-parameters]

该集表示以增量形式从开始到结束的一个数字序列。因此,(1,1,5) 将产生序列 1 2 3 4 5,(5,-1,1) 将产生序列 (5 4 3 2 1)。

使用迭代变量设置起始值 (Start#),然后逐步执行一组范围的值,直到该值超过所设置的终止值 (End#)。/L 将通过对 Start# 与 End# 进行比较来执行迭代变量。如果 Start# 小于 End#,就会执行该命令。如果迭代变量超过 End#,则命令解释程序退出此循环。还可以使用负的 Step# 以递减数值的方式逐步执行此范围内的值。例如,(1,1,5) 生成序列 1 2 3 4 5,而 (5,-1,1) 则生成序列 (5 4 3 2 1)。语法是:

看着这说明有点晕吧!咱们看例子就不晕了!
  1. @echo off
  2. for /l %%i in (1,1,5) do @echo %%i
  3. pause
复制代码
保存执行看效果,他会打印从1 2 3 4 5  这样5个数字(1,1,5)这个参数也就是表示从1开始每次加1直到5终止!

等会晕,就打印个数字有P用...好的满足大家,看这个例子
  1. @echo off
  2. for /l %%i in (1,1,5) do start cmd
  3. pause
复制代码

执行后是不是吓了一跳,怎么多了5个CMD窗口,呵呵!如果把那个 (1,1,5)改成 (1,1,65535)会有什么结果,我先告诉大家,会打开65535个CMD窗口....这么多你不死机算你强!

当然我们也可以把那个start cmd改成md %%i 这样就会建立指定个目录了!!!名字为1-65535

看完这个被我赋予破坏性质的参数后,我们来看最后一个参数

五、参数 /F

\迭代及文件解析

使用文件解析来处理命令输出、字符串及文件内容。使用迭代变量定义要检查的内容或字符串,并使用各种options选项进一步修改解析方式。使用options令牌选项指定哪些令牌应该作为迭代变量传递。请注意:在没有使用令牌选项时,/F 将只检查第一个令牌。

文件解析过程包括读取输出、字符串或文件内容,将其分成独立的文本行以及再将每行解析成零个或更多个令牌。然后通过设置为令牌的迭代变量值,调用 for 循环。默认情况下,/F 传递每个文件每一行的第一个空白分隔符号。跳过空行。

详细的帮助格式为:

FOR /F ["options"] %%variable IN (file-set) DO command [command-parameters]
FOR /F ["options"] %%variable IN ("string") DO command [command-parameters]
FOR /F ["options"] %%variable IN ('command') DO command [command-parameters]

带引号的字符串"options"包括一个或多个指定不同解析选项的关键字。这些关键字为:

        eol=c           - 指一个行注释字符的结尾(就一个)
        skip=n          - 指在文件开始时忽略的行数。
        delims=xxx      - 指分隔符集。这个替换了空格和跳格键的默认分隔符集。
        tokens=x,y,m-n  - 指每行的哪一个符号被传递到每个迭代的 for 本身。这会导致额外变量名称的分配。m-n格式为一个范围。通过 nth 符号指定 mth。如果符号字符串中的最后一个字符星号,那么额外的变量将在最后一个符号解析之后分配并接受行的保留文本。经测试,该参数最多只能区分31个字段。

        usebackq        - 使用后引号(键盘上数字1左面的那个键`)。
                        未使用参数usebackq时:file-set表示文件,但不能含有空格
                            双引号表示字符串,即"string"
                            单引号表示执行命令,即'command'
                          使用参数usebackq时:file-set和"file-set"都表示文件
                          当文件路径或名称中有空格时,就可以用双引号括起来
                            单引号表示字符串,即'string'
                            后引号表示命令执行,即`command`

以上是用for /?命令获得的帮助信息,直接复制过来的。
晕惨了!我这就举个例子帮助大家来理解这些参数!
在For命令语句的参数F中,最难理解的就是Delims和Tokens两个选项,本文简单的做一个比较和总结。
“For /f”常用来解析文本,读取字符串。分工上,delims负责切分字符串,而tokens负责提取字符串。如果把字符串当作蛋糕,Delims像刀子,用来切蛋糕,tokens像叉子,用来取切好的蛋糕。下面我们用实例来进行理解。
把以下内容保存为文本文件“歌曲列表.txt”,注意扩展名为“.txt”:
序号、歌手名-歌曲名.后缀名
1、饶天亮-玫瑰爱人.wma
2、高一首-我不愿错过.mp3
3、黃凱芹-傷感的戀人.MP3
4、黄灿-黄玫瑰.lrc
5、黎姿-如此这般的爱情故事.mp3
代码1:显示全部内容
@echo off
for /f %%i in (歌曲列表.txt) do echo %%i
pause>nul
运行结果:
序号、歌手名-歌曲名.后缀名
1、饶天亮-玫瑰爱人.wma
2、高一首-我不愿错过.mp3
3、黃凱芹-傷感的戀人.MP3
4、黄灿-黄玫瑰.lrc
5、黎姿-如此这般的爱情故事.mp3
讲解:
如果不使用参数“/f”,运行结果只显示括号里的文字字符“歌曲列表.txt”,而不能读取文本文件“歌曲列表.txt”中的内容。可见,“/f”是解析文本字符串的好工具。
一、delims
假如只要序号,不要歌手名、歌曲名和后缀名,如何办到?
代码2:默认提取第一列
@echo off
for /f "delims=、" %%i in (歌曲列表.txt) do echo %%i
pause>nul
运行结果:
序号
1
2
3
4
5
讲解:
"delims=、"表示定义顿号“、”为分隔符,并用该分隔符“、”切分文本字符串。字符串就是“歌曲列表.txt”里的内容,也就是文件里的文字和标点符号。
该顿号是原文中就有的。除了顿号“、”,原文中还有减号“-”和点号“.”,因此你也可以用它们来做分隔符。
代码3:用减号“-”做分隔符
@echo off
for /f "delims=-" %%i in (歌曲列表.txt) do echo %%i
pause>nul
运行结果:
序号、歌手名
1、饶天亮
2、高一首
3、黃凱芹
4、黄灿
5、黎姿
讲解:
因为,当减号“-”被用做分隔符时,每行内容被减号“-”分隔成前后两半,默认只显示前半部分,而后半部分连同分隔符减号“-”都被忽略(省略)了。
代码4:用点号“.”做分隔符
@echo off
for /f "delims=." %%i in (歌曲列表.txt) do echo %%i
pause>nul
运行结果:
序号、歌手名-歌曲名
1、饶天亮-玫瑰爱人
2、高一首-我不愿错过
3、黃凱芹-傷感的戀人
4、黄灿-黄玫瑰
5、黎姿-如此这般的爱情故事
讲解:
默认情况下,单纯使用delims而不用tokens时,只显示第一个分隔符前的内容,第一个分隔符和第一个分隔符后面的内容将被忽略。
代码5:定义多个分隔符
@echo off
for /f "delims=、-." %%i in (歌曲列表.txt) do echo %%i
pause>nul
运行结果:
序号
1
2
3
4
5
讲解:
原因是,当定义顿号“、”、减号“-”和点号“.”三个标点符号为分隔符后,原文被分隔成四个部分。
如第二行“1、饶天亮-玫瑰爱人.wma”将被分隔成“1”、“饶天亮”、“玫瑰爱人”和“wma” 四个部分。
从第一行到最后一行,每行的每个部分对应下来相当于一个竖列。因此,原文就有“序号”、“歌手名”、“歌曲名”、“后缀名”四列。
一般情况下,只读取第一列的内容。后面的内容需要用tokens选项提取。
详细出处参考:http://www.jb51.net/article/17927.htm

(四)tokens=x,y,m-n 提取列

格式:
FOR /F "tokens=x,y,m-n" %%I IN (Command1) DO Command2
用法:
一句话总结:提取列。
通俗讲,共同提取每一行的第m小节的内容。
因此,可以用该命令来指定提取文本信息。
tokens=有时表示提取全部。
tokens=m表示提取第m列。
tokens=m,n表示提取第m列和第n列。
tokens=m-n表示提取第m列至第n列。
Tokens=*表示删除每行前面的空格。忽略行首的所有空格。
tokens=m*提取第m列以后的所有字符,星号表示剩余的字符。
tokens=m,*提取第m列以后的所有字符,星号表示剩余的字符。
输出变量的个数由定义了的tokens决定。
在 FOR 语句中显式声明 %%i。使用tokens= 隐式声明%%j 和%%k。只要不会引起试图声明高于字母“z”或“Z”的某个变量,则使用tokens= 可以指定最多 26 个输出变量。

接着前面的例子“静夜思”。
如果我要提取第三小节“举头望明月”,如何做到?
@echo off
for /f "delims=, tokens=3" %%i in (静夜思.txt) do echo %%i
pause>nul

讲解:
首先用delims=,表示命令要用逗号作为诗句的分隔符将四句分成四小节。然后用tokens=3提取第三小节,即“举头望明月”了。
delims=和tokens=共用一对双引号,如果单独用双引号,则FOR命令返回的只能是它们之中的一个。因为在第一节说过,FOR是逐一读取命令的,将delims和tokens分开后,FOR只能一次读取一个,不能一次全部读取。

注意:
Tokens常和delims一起使用。
首先,一行内容被delims用分割符号如逗号等分隔成许多小段或小节。
然后,tokens才能提取每行之间对应的这些小段或小节——列。具体看下面例子。

例:提取前面例子文本“a.txt”中每行的第三段内容“ccc”、“kkk”、“ggg”、“考试”。
@echo off
for /f "skip=1 delims=,, tokens=3" %%i in (a.txt) do echo %%i
pause>nul
注意:为什么kkk不出现呢?

例:如何屏蔽掉文本“a.txt”中的标点符号?
@echo off
for /f "skip=1delims=,, tokens=1-4" %%i in (a.txt) do echo %%i %%j %%k %%l
pause>nul

讲解:
%%i %%j %%k %%l是输出变量,它的个数由tokens后面的(m-n)决定,一般有(n-m+1)个,但不能超过Z。
并且%%后面的字母存在先后顺序,%%a %%b是顺向,倒过来则是逆向的。
代行号的tokens=m*,星号表示m后面的所有剩余的列。
例:
for /f "tokens=*" %%i in (a.txt) do echo %%i
讲解:
没有指定具体的列,"tokens=*"将提取全部列,后面只需一个输出变量%%i。

例:
for /f "tokens=2*" %%i in (a.txt) do echo %%i %%j
讲解:
"tokens=2*"提取第二列以后的所有字符,星号表示剩余的字符。输出变量%%i对应于2的输入变量,%%j对应于星号的输入变量。
注意:
这里没有使用delisms但却以空格分隔了,是因为FOR默认空格是做分隔符的。

例:屏蔽掉“易经.txt”中的标点符号:
@echo off
for /f "tokens=1-5 delims=:," %%a in (易经.txt) do echo %%a %%b %%c %%d %%e
pause>nul
讲解:
当delims定义了两个分隔符“:”和“,”时,提取列要用到tokens。
有五个列,所以tokens要定义提取第一列至第五列,即1-5,相应地,后面需要五个输出显示变量%%a %%b %%c %%d %%e。你也可以这样修改,避免过多的变量符号【补充?】
你也可以将最后多余的句号定义为分隔符“delims=:,。”将其屏蔽掉。

练习:
1、 请简单说说tokens的作用
2、 Tokens=1,3-5后面的输出变量需要多少个?
3、 请使用tokens提取下面网页的标题《硬盘知识及故障大总汇(页 2)》:
手机,3G手机,智能手机,手机电影,手机软件,手机游戏,铃声,主题,图片,电子书,手机维修,手机大全,手机报价,下载,智能手机的测评,使用心得 硬盘知识及故障大总汇(页 2) - 电脑技术交流区 - 3g365智能手机论坛 - powered by Discuz! Archiver.mht
 
 
 
 
"delims=" 的含义是取消默认的分隔符,所以会把行上的内容照搬下来,而 "tokens=*" 表示获取行上的所有内容,但是会忽略行首的所有空格。
-
比较以下两段代码的执行结果差异:
1、
@echo off
for /f "delims=" %%i in (test.txt) do echo /%%i/
pause
2、
@echo off
for /f "tokens=*" %%i in (test.txt) do echo /%%i/
pause
test.txt 的内容为: abc 。行首有若干空格。
看到有什么差别了吗?
原因:"delims=" 的含义是取消默认的分隔符,所以会把行上的内容照搬下来,而 "tokens=*" 表示获取行上的所有内容,但是会忽略行首的所有空格。 -
QQ空间 新浪微博 腾讯微博 搜狐微博 人人网 开心网 百度搜藏 更多 0Tags:批处理 delims tokens
详细出处参考:http://www.jb51.net/article/15610.htm
 
 


For命令例1:****************************************
  1. @echo off
  2. rem 首先建立临时文件test.txt
  3. echo ;注释行,这是临时文件,用完删除 >test.txt
  4. echo 11段 12段 13段 14段 15段 16段 >>test.txt
  5. echo 21段,22段,23段,24段,25段,26段 >>test.txt
  6. echo 31段-32段-33段-34段-35段-36段 >>test.txt
  7. FOR /F "eol=; tokens=1,3* delims=,- " %%i in (test.txt) do echo %%i %%j %%k
  8. Pause
  9. Del test.txt
复制代码
运行显示结果:

11段 13段 14段 15段 16段
21段 23段 24段,25段,26段
31段 33段 34段-35段-36段
请按任意键继续. . .

为什么会这样?我来解释:
eol=;          分号开头的行为注释行
tokens=1,3*    将每行第1段,第3段和剩余字段分别赋予变量%%i,%%j,%%k
delims=,-     (减号后有一空格)以逗号减号和空格为分隔符,空格必须放在最后


For命令例2:****************************************
  1. @echo off
  2. FOR /F "eol= delims=" %%i in (test.txt) do echo %%i
  3. Pause
复制代码
运行将显示test.txt全部内容,包括注释行,不解释了哈。

For命令例3:****************************************

另外/F参数还可以以输出命令的结果看这个例子
  1. @echo off
  2. FOR /F "delims=" %%i in ('net user') do @echo %%i
  3. pause
复制代码
这样你本机全部账号名字就出来了把扩号内的内容用两个单引号引起来就表示那个当命令执行,FOR会返回命令的每行结果,加那个"delims=" 是为了让我空格的行能整行显示出来,不加就只显示空格左边一列!

基本上讲完了FOR的基本用法了...如果你看过FOR的系统帮助,你会发现他下面还有一些特定义的变量,这些我先不讲.大家因该都累了吧!你不累我累啊....

所谓文武之道,一张一弛,现休息一下。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多