for %%var in (fileset) do comm | 文件集合 | |
for /d %%var in (directorySet) do comm | 目录集合 | 不包括子目录 |
for /r [[driver:]path] %var in (fileset) do comm | 子目录中的文件 | 对以[path]指定为起点的的整个目录树进行处理; |
for /l %%var in (start,step,end) do comm | 遍历一系列的值 | 命令重复执行n次; |
for /f ["optins"] %%var in (file-set) do comm | 分析文本文件中的每一行 | 以行为基础进行分析 |
for /f ["optins"] %%var in ("string") do comm | 分析字符串 | |
for /f ["optins"] %%var in (command) do comm | 分析命令输出 |
helps you interate through groups of files and directories,and to parse text files,strings and command output on a line-by-line basis.(1 对有空格的文件名的文件的处理要加"";2 符号前一定要有空格;3 In (`command`)(esc键下的一个符号;);4 在批处理程序中使用 FOR 命令时,指定变量请使用 %%variable,而不要用 %variable。变量名称是区分大小写的,所以 %i 不同于 %I.5 interator变量名必须石a-b,A-B内,大小写敏感,是一个初始变量;)
循环处理文件 for %a in (path.*.*) do command;
循环处理目录 for /d %a in (directoryset) do command;
循环处理某一目录下的全部子目录的某类文件 for /r path %a in (fileset) do command
循环处理某一目录下全部目录及子目录 for /r path/d %a in (fileset) do command
循环解析文本 for /f %a "eol= skip= delims= tokens= usebackq" in (txt file set or `command` or "text") do command;
循环处理某一命令或命令组;for /l %a in (start,step,end) do command;
选项 | 选项描述 | 实例 | 实例描述 | |
eol | 设置行尾注释字符,行尾注释字符后的所有数据都被命令看成是注释; | eol=# | 将#设置为行尾注释字符;忽略以#开始的行; | end of line |
skip | 设置文件起始处跳过的行数 | skip=5 | 通过命令跳过源文件中的1-5行; | |
delims | 设置名字段之间的分隔符,默认情况下为制表符或空格;(一行可以定义不同的符号将行分隔为不同的部分) | delims=,.: | 指定逗号、句点、分号为分隔符 | delimit |
tokens | 为每一源行设置令牌字段,如果以a或A作为起始的迭代变量,则至多可以指定26个令牌。默认情况下,只对第一个令牌进行检查.(指定处理的字段) | tokens=1,3 | %%A:wu %%B:wh | |
tokens=2-4 | %%A:wanqun %%B:wh %%C:wwuhn@hotmail.com | |||
tokens=* | 把每一行当做整体处理,而不分割为字段 | |||
usebackq | 规定可在源指定符中使用引号:对文件名使用双引号,对命令使用反引号(与~一起),对字符串使用单引号; | usebackq | 激活该选项 | quotation marks |
for命令是一种对一系列对象依次循环执行同一个或多个命令的在命令行或批处理中运行的命令,结合一些Windows管理中的程序后,其处理功能强大、应用灵活方便程度令人
基本格式:for [/参数] %变量 in (集) do 命令(这里写的是在命令行里用的格式,如果是在批处理中,需要把其中%再多加个%形成%%):
for是批处理中唯一的循环流程控制命令,它主要有以下几项功能:
1 无参数时: 循环处理文件(某一路径下的文件集,或当前目录下的文件集,多个文件集可用空格分隔);
2 /d 循环处理目录;
3 /r 循环处理目录内的文件及子目录;
4 /l 循环指定的次数;
5 /f 读取文本,以文本作为参数,批次执行循环体语句;
变量:(记住如果是在批处理中使用for命令时,变量前的%需改为%%)这个变量名是由单个字母组成且区分大小写(原帮助是这么说的,实际运用中用单个数字作为变量名试过证明也可行),如%B和%b代表的是不同的变量。FOR命令会在每次循环中,把in (集)中读取到的值赋于这个变量,以便其后的命令中引用。
集:由系列文件、字符串或由命令产生的内容形成的集合(当然可用通配符 * ?,还可引用环境变量),FOR命令是按一定顺序和规律分次读取集中内容,赋值给变量,并执行do后的命令,进行循环下一轮,直至集中内容读取完毕,而括号是格式必须的(括号前面需要要有空格)。
命令:可以是任何合格的DOS命令或外部可被DOS调用的程序,且可采用括号把多条命令括起来,在一次循环中执行。
附注:由于一些目录或文件名可能会有空格,所以很多时候集里和命令里往往需要用英文引号括起来(但有时引号里的内容可能会被认为是字符串)表示是一整体,下面开始的有些例中为简捷起见,忽略文件名或目录名带空格这种情况。
现在按参数分类举例解释其用法:
一、参数 /d,循环处理目录for /d %%变量 in (集) do 命令
/d 参数是指定仅对目录而不是文件执行的for命令。
例1:
在命令行输入(不是在批处理,之后不再解释)
for /d %a in (c:\*.*) do echo %a
运行会把C盘根目录下的全部目录分次显示出来,而不显示文件名
看起来有点乱,如果把命令提示回显关闭就清晰了:
for /d %a in (c:\*.*) do @echo %a
二、参数 /R,循环处理目录内的文件及子目录/R参数之后还可带盘符及路径
for /r 此处可以带有路径 %变量 in (集) do 命令
注意参数的两个限定:
在/r 之后的那个路径,指包含它之下的整个目录树(相当于DOS命令tree里的范围)中的所有目录,如果仅为一个英文句点 . ,是指当前路径下的目录树,如果省略了路径则特指当前目录,而之后的in (集)则相当于与前面每个目录相配的文件集
这里按in(集)中有无通配符分两种情况
1)in(集)中没有通配符
指定的是单个文件或列举的具体文件(多个文件名之间用分隔符分隔,如空格、逗号等)
例2
@echo of
for /r . %i in (abc.txt) do echo. > %i
echo on
注:这里for /r 后的路径仅有一个 . 而后面每个循环中echo. > %i相当于创建一个仅有一空行的文本文件,整体效果是在当前目录下包括子录,每个目录中建一个abc.txt。
例3 (放入批处理中)
@echo off
rem 显示d:盘中所有文件名为file1和file2的列表
for /r d:\ %%h in (file1,file2) do if exist %%h echo %%h
pause
2) in(集)中含有通配符*或?
这种里面的do命令将处理前面 /r指定的目录系列里每个含有in(集)中文件的项,而不去理会不含有相配文件的那些目录
例4:
@echo off
rem 删除C盘中所有*.chk的文件
for /r c:\ %%h in (*.chk) do del /q %%h
pause
注:del /q 表示用安静模式删除(不需确认)
for /L %%变量 in (起始值,每次增值,结束时的比较值) do 命令
(上面L也可用小写,主要为了视觉上不与数字1混淆而没用小写)
(起始值,每次增值,结束时的比较值)相当于一个等差数字序列,从“起始值”的数字开始,每次增加多少(也可设定为负数)为“每次增值”,并与“结束时的比较值”比较,超出则退出for循环(也不执行本轮后面的do 命令)
例如 (1,1,3) 将产生序列 (1 2 3);(1,2,9)将产生序列(1 3 5 7 9);(5,-1,1) 将产生序列 (5 4 3 2 1);(1,3,18)将产生序列(1 7 10 13 16)
例5
@echo off
::在D盘建立aa1~ aa5五个文件夹
for /L %%i in (1,1,5) do md d:\aa %%i
pause
注:在行首,单个冒号:接一名称,是标号行,对应于批处理中go后指向的位置,而双冒号::一般是用来作注释用,注释在批处理中可以用rem加空格来表达,二者稍有不同,rem注释在未关闭命令回显时会在屏幕显示出来,而::则什么情况下都不会显示。
四、参数 /f,解析文本并处理输出结果这个参数/f将会打开(集)里的文件,使for命令能处理文本文件的读取和添加删除替换等编辑性的操作,可谓功能强大,因此也相对复杂一些。
文件名-集 | ||
for /f “选项” %变量 in ( | “字符串”-集 | ) do 命令 |
‘命令’-集 |
/f 后可以带有几种选项,不带选项当然也是合格的格式,而带有参数则必须以引号整体括起来,后面的集里主要由三种形式形成的,最终在for循环中的每一轮中会形成读取一行字符串,来给指定的%变量、以及给由于选项中派生出附加变量赋值后,执行do后面的命令
下面以例子来具体说明和逐步理解各分项的用法例6
假定d:\abc.txt内容如下:
姓名 性别 年龄 等-级
张三 男 36 A-1
李四 男 29 B-2
赵六 女 31 A-2
执行如下命令:
for /f %c in (d:\abc.txt) do @echo %c
则屏幕上显示:
姓名
张三
李四
赵六
解释:这是for /r 在“%变量”前缺省参数选项时的情况,循环中每轮会默认以空格为分隔,在打开的文件中逐行给字符串分段,又因为没给增添附加变量(即仅一个变量%c)则仅把第一段的字符赋给%c,再执行 do后的命令,然后进行循环的下一轮,并且默认忽略空行
改一下:
for /f “skip=1 tokens=1,4 delims= ” %c in (d:\abc.txt) do @echo %c %d
显示为:
张三 A-1
李四 B-2
赵六 A-2
解:
skip:跳过前面指定的行数。
eol:忽略以指定字符开始的行。
delims:用于将行内容分割为几个部分,默认以空格、Tab为分割点,也可以在等号后指定其它分割点,如果想忽略掉默认的空格:"delims="(=后没有空格);
tokens:指定取用的列序号,与变量进行对应,如果取了三列,则对应三个变量,每个变量的取值个数=文本总行数-skip-eol;
usebackq:用一读取包含空格的文件名;
delims= 在一行中,用什么单个符号(可以有多字符组合,之间也不能加空格,被理解为多项单个字符,如要空格符须放最后)来分隔字符串作为读取赋值的单元(形成一段),本例中等号后是空的表示仅用空格来分隔。——用什么刀来切分
tokens=1,4 这个等号后的数字表示依次取第几个被分隔的字符串段,来分别赋给%变量及顺序附加的变量,本例取第1个段赋给%c,第4个段赋给c后的一个变量也就是赋给%d,并且,可以写成tokens=1,2,5-7 或tokens=1,2,3* 或tokens=1,2,5,7 分别表示取第1,2,5,6,7(依次赋给%c, %d, %e, %,f, %g共5个变量)、1,2,3及3后的所有段(要赋给3个变量)、1,2,5,7(要赋给4个变量),tokens=后的数字号可以不按顺序,但书写的顺序与分配给变量的顺序是对应的,这是赋值,至于之后do命令中用不用是另一回事。换句话 ——最多只需取哪几段
in (变量) 中的那个变量,代表起始的一个变量名,按tokens中定义的总个数来扩充附加变量名,如总个数为3,则%c 就附加%d和%e ,要是%C就附加%D%E… 本例中tokens=1,4仅需两个,起始的是in () 括号中的%c 则每行中第一段赋给%c,第4段赋给变量%d
以第二行(第一行被skip=1跳过了)为例,在 “张三 男 36 A-1 ” 中(正好也是用的空格分隔)共被空格之刀切为五段,只要第1、4,即张三赋给%c, A-1赋给%d,执行@echo %c %d然后下一轮…而空行照旧被省去了。
再稍改一下:
for /f “skip=1 tokens=4,1 delims=- “ %c in (d:\abc.txt) do @echo %c %d
则显示为:
A 张三
B 李四
A 赵六
例7
假定d:\aa.txt内容如下:
Volume in drive D is MYDA
Volume Serial Number is C35D-8998
Directory of D:tmp
09/25/2001 10:40 AM 11,235 yg0925.txt
11/12/2001 04:29 pM 795 buple.txt
04/11/2002 04:18 AM 2,043 vitn.txt
3File(s) 12,673 bytes
0 Dir(s) 5,020,200,655 bytes free
在命令行输入:
for /f "skip=5 tokens=5" %a in (d:\aa.txt) do @echo %a
会显示:
yg0925.txt
buple.txt
vitn.txt
free
本意想把文件里列出的文件显示出来(当然也可以换成对文件进行其他命令操作)
通过skip=5 忽略掉前5行,默认以空格分隔后tokens=5取每行第五段字符就顺利地把文件名赋给变量%a,美中不足最后一行取了个不是文件名的(当然可用其他方法处理这个多余的只是for/f中没提供忽略最后几行的格式),而倒数第二行则无第五段。
显然例中aa.txt里的内容是某次执行dir命令后的内容。它可用类似命令:
dir > d:\aa.txt来建立
题外话,如果在dir中加入合适的参数/b,就可以回避多余的部分,还可加入/ad只显示目录,加入/a-d只显示文件等
那么,我们完全可以直接书写命令放入in后的(‘命令’-集)中
for /f "skip=5 tokens=5 " %a in ('dir') do @echo %a
效果一样。
注:命令集需用单引号括起来以表示不是文件集,如用双引号括起来则表示是字符串集,本例是为了说明for命令的用法,真正有这种用途也愿意用前面“题外话”的方法。如果你在执行本例后什么也没显示,你需要先用集里的命令先执行一次,看它显示的格式,也许需要把tokens=5 改成tokens=4 或许还应当给dir加上参数 /a-d以回避显示出目录。
如果集里是由多个文件组成,那么处理完一个文件后又处理完又去处理另一个文件,每个文件行数不同循环次数(do命令的次数)也将因此不同。
如果集里是由命令产生的系统,那么你必须首先熟悉该命令执行后会产生怎样效果的字符系统,才能正确安排后面的do命令
画龙点睛:无论in后的集是哪种形式,for/f 都最终分解为字符串,按需要是否“忽略几行”(skip=)、“用什么刀来切分”(delims= )、“最多只需取哪几段”(tokens=)将集里形成的字符串,逐行地分段赋给%或%%后的变量及可能顺延扩展出的变量,以执行do后的命令,每一行即为一轮循环。这里没完整说明全部参数,请在命令行用for/?查看。(下面的斜体字是复制的帮助里的内容)
例如:
对于带有空格的文件名,您需要用双引号将文件名括起来。为了用这种方式来使用双引号,您还需要使用 usebackq 选项,否则,双引号会被理解成是用作定义某个要分析的字符串的。——换句话说,带有usebackq(放在for /f 之后的引号里)参数时 in ()里用双引号表示的仍是文件名。
还有一个选项eol= :前面所说skip=是表示忽略开始的几行,其实默认状况还忽略所有分号“ ; ”开始的行,如果你想不忽略分号开始的行,或者想忽略自己指定一字符开始的行就可以在for /f 之后那引号参数里使用eol=你自己定义的字符,但它不像delims=的那样可定义多个,只允许定义一个。
另一花样:可以用 %~ 操作符将文件名分离成文件名、扩展名、盘符等独立部分 ,请看for/?中的解释(其中示例的变量为%I):
另外,FOR 变量参照的替换已被增强。您现在可以使用下列选项语法:
%~I - 删除任何引号("),扩充 %I未被定义,或者没有找到文件,此组合键会扩充到空字符串
可以组合修饰符来得到多重结果:
%~dpI - 仅将 %I 扩充到一个驱动器号和路径简记:凡是 %~ 打头的操作符,都是文件名或环境变量的分离操作。而每项要想运用自如,则需要付出辛勤的练习。
练习:
遍历C、D盘,查找已知文件名(接收键盘输入),把其存放位置、时间,记录到D:\mynote.txt 记录格式如:
xx年xx月xx日 经查找在C盘、D盘的xx文件情况如下:
时间 位置
。。。。。 。。。。。。
。。。。。 。。。。。。
。。。。。 。。。。。。
。
。
。
提示:可能用到的DOS命令、变量、参数: echo、set 、set/p 、%date%、%~ >、>>
总结及提示:
for 命令的实际用法基本上已终结,但是仅此是不能写出强大功能的批处理的,它只是一条DOS命令,需要熟练一些其他的DOS命令和Windows系统提供的命令,组合运用,才能充分发挥其强大、实用的功能,使得一些复杂事情,处理起来意想不到的简洁方便。
附:常见在批处理for命令中需要的一个的命令或者叫环境设置:
for命令实际上是会作循环,如果在每轮的命令中改变某环境变量值,在默认状态,一条for命令用%环境变量%只取一次值的,那么下轮循环中再用时还是改变前的值(包括do后面带有括号里的多条命令的执行期间),就没达到预期目的,为此,引入下面命令:
setlocal enabledelayedexpansion
开始批处理文件中环境改动的本地化操作,并启动延缓环境变量扩展。在执行SETLOCAL 达到批处理文件结尾时,对于该批处理文件的每个尚未执行的 setlocal 命令,都会有一个隐含的 endlocal 被执行。
在取变量值时,用!变量名!可以动态取值,延迟环境变量扩充允许您使用一个不同的字符(惊叹号)在执行时间扩充环境变量。这个用法实际是属于在批处理中所有复合型命令都需要注意的。如果批处理结束后不希望将改变的环境保留,建议总是加上setlocal 。
要是结合一些其他复杂些的有关系统的、网络的命令(如wmic、net)进来,那才是方显FOR英雄本色,比如遍历本地磁盘可以用命令:wmic logicaldisk where "drivetype=3" get name 显然要在所有磁盘里查找某文件并作相应操作就很容易了,用好for命令也是需要其他命令和计算机基础配合的。呵呵,本人水平有限,写的只是低级层次的...但愿能对有缘来这里看的初学DOS的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选项提取。
二、tokens
假如只要歌手名和歌曲名,不要序号和后缀名,如何办到?
代码6:提取单列
@echo off
for /f "tokens=2 delims=、." %%i in (歌曲列表.txt) do echo %%i
pause>nul
运行结果将显示:
歌手名-歌曲名
饶天亮-玫瑰爱人
高一首-我不愿错过
黃凱芹-傷感的戀人
黄灿-黄玫瑰
黎姿-如此这般的爱情故事
讲解:
用delims定义顿号“、”和点号“.”作为分隔符,将原文分成三部分。
如第六行“5、黎姿-如此这般的爱情故事.mp3”被分割成:
第一部分(第一列):5
第二部分(第二列):黎姿-如此这般的爱情故事
第三部分(第三列):mp3
“tokens=2”表示用tokens提取第二列的字符串,即“黎姿-如此这般的爱情故事”。
没有被tokens定义提取的第一列和第三列将被忽略。
假如只要序号和歌曲名,而不要歌手名和后缀名,如何办到?
代码7:提取多列
@echo off
for /f "tokens=1,3 delims=、-." %%i in (歌曲列表.txt) do echo %%i %%j
pause>nul
运行结果将显示:
序号 歌曲名
1 玫瑰爱人
2 我不愿错过
3 傷感的戀人
4 黄玫瑰
5 如此这般的爱情故事
讲解:
“delims=、-.”表示定义顿号、减号和点号为分隔符。
“tokens=1,3”表示只提取第一列和第三列。
“%%i %%j”对应于“token”后面的列数。有多少列就要有多少个输出变量,并且各变量中的字母存在先后顺序。
如何只提取文字,不要标点符号?
代码8:忽略分隔符
@echo off
for /f "tokens=1,2-4 delims=、-." %%i in (歌曲列表.txt) do echo %%i %%j %%k %%l
pause>nul
运行结果:
序号 歌手名 歌曲名 后缀名
1 饶天亮 玫瑰爱人 wma
2 高一首 我不愿错过 mp3
3 黃凱芹 傷感的戀人 MP3
4 黄灿 黄玫瑰 lrc
5 黎姿 如此这般的爱情故事 mp3
讲解:
默认情况下,用做分隔符的标点符号将被忽略。
“tokens=1,2-4”中的“2-4”表示第二至第四列。
三、小结
“For /f”
一句话总结:解析文本,读取字符串。
Delims的语法:
FOR /F "Delims=符号集" %%I IN (Command1) DO Command2
一句话总结:忽略分隔符,切分字符串。
delims的意义包括两个方面:
第一、指定原文中的标点符号作为分隔符。使得文本被划分为许多小部分,方便使用批处理命令读取和编辑。
第二、读取第一个分隔符之前的内容。忽略第一个分隔符和分隔符后面的内容,如需读取和编辑,需要使用tokens等命令。
注意分隔符和标点符号的联系和区别。
分隔符就是原文中的标点符号,可以是一个标点符号也可以是多个。但原文中的标点符号不一定是分隔符。并且分隔符不一定是标点符号,字母和中文也是可以用作分隔符的。
分隔符需要定义,即用”delims=”来指定,等于号后面跟被用来做分隔符的标点符号,该标点符号来自原文。
当有多个标点符号被定义为分隔符时,标点符号之间没有空格。当用空格做分隔符时,空格应该放在其它用作分隔符的标点符号之后。
即使不使用delims,默认情况下,批处理也将空格作为分隔符。如文件名“Program Files”中含有空格时,批处理一般只读取空格前的“Program”,剩下的“Files”被忽略了。
例:
代码9:空格默认作为分隔符
@echo off
for /f "delims=" %%a in ("伟大的中国人民万岁 万岁 万万岁") do echo %%a
pause>nul
运行结果:
伟大的中国人民万岁 万岁 万万岁
讲解:
“delims=”等号后面没有空格,代表取消默认以空格作为分隔符,相当于“tokens=*”,提取全部字符;等号后面有空格时表示定义空格为分隔符,此时delims可以省略。
批处理默认空格是分隔符,分隔符会隐藏第一个分隔符后面的所有内容。为了显示完整的信息,所以有必要取消该功能。
因此,当文件名或路径中含有空格时,需要用双引号括住。如果不使用双引号,括号内的内容将被当做文件名,如果文件名不存在,将提示“系统找不到……”。
如果不使用“delims=”,即使使用双引号,也只能显示第一个空格前面的字符串,后面的字符串将被默认忽略。
Tokens的语法:
FOR /F "tokens=x,y,m-n" %%I IN (Command1) DO Command2
一句话总结:提取列。
Tokens的意义就是,提取指定的列。
注意列与句的联系与区别。
文本内容由许多文字字符串组成,它们被标点符号分隔,两个标点符号之间的语句我们称为“句子”。
当标点符号被“tokens=”指定为分隔符之后,文字将被分成多个部分。对应的每行的每个部分我们称之为“列”。
一列可能是一个句子,也可能包含多个句子,视delims定义的标点符号而定。
其它方面:关于“行”的提取,前面做过一个很简单的:
列出C盘中所有的文本文件
for /r c:\ %%B in (*.txt) do echo %%B
列出%systemroot%下的所有目录及子目录
for /r %systemroot% /d %%B in(*) do echo %%B
列出C盘下的所有exe文件,仅列出文件名;
for /r c:\ %a in (*.exe) do @echo %~na
列出C盘下的所有exe文件,仅列出文件名+扩展名;
for /r c:\ %a in (*.exe) do @echo %~nxa
对一组文件中的每一个文件执行某个特定命令。
FOR %variable IN (set) DO command [command-parameters]
FOR %variable IN (fileSet) DO command [command-parameters]
%variable 指定一个单一字母可替换的参数(只能是字线,%%variable用在批处理)。
(set) 指定一个或一组文件,路径+文件名。可以使用通配符,可以作空格分隔。
command 指定对每个文件执行的命令(在命令中引用%variable做参数)。
command-parameters 为特定命令指定参数或命令行开关。
如果启用命令扩展,则会支持下列 FOR 命令的其他格式:
/D和/R是与目录或文件有关的命令;
/D是对指定集中的目录进行处理;
FOR /D %variable IN (directorySet) DO command [command-parameters]
如果集中包含通配符,则指定与目录名匹配,而不与文件名匹配。
/R有时用于通过遍历文件夹查找一个文件或文件夹,速度比tree d:慢,但更实用;
/R是以指定的目录为基准,对其下的所有子目录、指定的集的限制进行处理;
FOR /R [[drive:]path] %variable IN (subdirectorySet) DO command [command-parameters]
检查以 [drive:]path 为根的目录树,指向每个目录中的 FOR 语句。
如果在 /R 后没有指定目录规范,则使用当前目录。如果集仅为一个单点(.)字符,则枚举该目录树。
/L可以按指定的(end-start)/step+1次数进行循环,同时变量生成:start,start+1*step+start+2*step…end)这样一个数组;
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)
/F parsing file content and command output or text;
for /f "tokens=*" %%a in ('dir') do ( command[command-parameters])
for循环语句用于分析"dir"命令所显示的字符串,"/f"参数表示for语句以解析方式工作。For语句首先执行括号中"dir"命令,然后进入for语句块执行相应的命令。"tokens"参数只有一个"*",表示"%%a"将依次代表"dir"命令输出的每一行。For语句循环次数等于"dir"命令显示结果的行数。
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](注意符号是`,esc 下的符号)
fileset 为一个或多个文件名(以空格分隔)。继续到 fileset 中的下一个文件之前,每份文件都被打开、读取并经过处理。处理包括读取文件,将其分成一行行的文字,忽略空行,然后将每行解析成零或更多的符号。然后用已找到的符号字符串变量值调用 For 循环.
循环命令,只要条件符合,它将多次执行同一命令或命令组。
for [%%f] in (集合)do (命令)
集合set,指定要用指定命令处理的一个或多个文件,目录,数值范围或文本字符串所执行的命令;
for /l %%i in (1,2,10) do md %%i
上述语句在批处理文件中的作用是创建5个文件夹,文件夹名称依次为1,3,5,7,9.可以发现,%%i的结束值并晨end的10,而是不大于end的一个数;
语法:
for %%var in (fileset) do command[command-parameters]
%%var:指定一个单一字母可替换的参数.
(set):指定一个或一组文件.可以使用通配符;
command:指定对文件执行的命令;
command-parameters:为特定命令指定参数或命令行开关.
如果命令扩展被启用,则下列额外的for命令格式会受到支持;
1 for /d %%var in (set) do command [command-parameters]
如果集中包含符,则指定与目录名匹配,而不与文件名匹配;
for /r [[driver:]path] %var in in (set) do command [command-parameters]
检查以[drive:]path为根的目录树,指向每个目录中的for语句.如果在/r后没有指定目录,则使用当前目录.如果集为一个单点(.)字符,则枚举该目录树.
for /l %%var in (start,step,end) do command[command-parameters]
该集表示以增量形式从开始到结束的一个数字序列.
命令行中的for语句主要用于石厅局级的文件或目录中进行迭代处理,并以行为基础分析文本文件\字符串以及命令的输出信息;
do (statement),statement可以是单一命令,也可以是使用命令管道\命令链\命令分组等技术组合起来的多条命令;
如果需要重复地执行一条命令或一系列命令,可以使用for语句;
主要用于在成组的文件与目录中进行迭代处理,并以行为基础分析文本文件、字符串、命令的输出信息;
for interator do (statement)
interator:用于控制for循环的执行。对interator中每一个步骤或元素,都会执行特定的。它可以是单一的一条命令,也可以是使用命令管道、命令链、命令分组等技术组合起来的多条命令;
interator通常包含:
1 一个初始化变量(要使用的值的占位符);
变量只存在于for循环的上下文中;
变量名必须在a-z或A-Z的范围内,比如%%A、%%B、%%C.
变量名大小写敏感,也就是说,%%A与%%a是不同的;
2 一组需要反复执行的元素(需要遍历的一组文件或某范围内的一组值),
1 遍历一系列的值
for /l %%var in (start,step,end) do comm
step可以使用负值;
运行流程:
首先对内部变量start,step,end进行初始化,将其赋值为应用中实际指定的值。之后,对start值为end值进行比较,如果start值可以按step中指定的值进行递增或递减操作,则条件为真(或按照另一种约定,条件为假),根据差别条件的真假判断是否需要执行语句。在条件为真的情形下,使用start值执行语句,并根据指定的step值对初始值进行递增或递减操作,之后重复这一过程直至遍历所有的值,或者条件发生变化。在条件为假的情况下,退出for循环语句,并跳到脚本中的下一语句执行;
for /l %%b in (0,2,10) do @ echo %%b
该语句的输出为
0
2
4
6
8
10
2 在成组的文件中进行迭代操作
for %%var in (fileset) do comm
fileset可以为如下的形式:
1 通过文件名指定的单独文件,如myfile.txt.
2 通过文件名通配符指定的一组文件,如*.txt.
3 通过多个文件名(使用空格分隔)指定的多个或多组文件,如*.txt *.rtf *doc.
for %%B in (c:\users\wwu\*.txt) do @echo %%B
for %%B in (%systemroot%\*.txt %systemroot%\*.rtf %systemroot%\*.doc) do @echo %%B
for %%B in (%systemroot%\*.txt %systemroot%\*.rtf %systemroot%\*.doc) do @echo %%B & move c:\data
3 在目录中迭代执行
for /d %%var in (directorySet) do comm
对目录的迭代处理与对文件的迭代处理是一样的,所不同的是,此时指定的是目录路径而不是文件路径。
for /d %%B in (%systemroot%\*) do @echo %%B
for /d循环对指定的目录集进行迭代处理,但不包括这些目录中的子目录。要访问子目录及整个目录结构,可以使用for /f循环;
也可以使用空格分隔目录名:
for /d %%B in (%systemroot% %systemroot%\*) do @echo %%B
文件迭代也可以和目录迭代技术结合起来,以便对目录集中的所有文件进行处理:
for /d %%B in (%appdata% %appdatat%\*) do (@ for %%C in ("%%B\*.txt") do echo %%C)
对以[path]指定为起点的的整个目录树(逐级子目录的文件)进行处理;
for /r [[driver:]path] %var in (fileset) do comm
如果path缺省,则默认为当前目录;
如,列出c:\中的所有文本文件
for /r c:\ %B in (*.txt) do @echo %B
for /r c:\ %B in (*.docx) do @echo %B
/d与/r结合起来使用,如下例,列出了 %systemroot% 下的所有目录和子目录
for /r %systemroot% /d %B in (*) do @echo %B
4 分析文件的内容与输出
for /f ["optins"] %%var in (source) do comm
for /f ["optins"] %%var in (file-set) do comm
for /f ["optins"] %%var in ("string") do comm
for /f ["optins"] %%var in (command) do comm
optins用于设置文本匹配选项;
in (source)用于指定文本的来源;
comm指定了在文本匹配时要执行的命令;
source指定的文本是以行为基础进行分析,文本的每行被命令当作一个记录处理;记录(或行)中不同的字段由特定的字符分隔开(比如制表符、空格,默认情况为空格)。通过替换技术,命令执行时会使用变量的实际值来替代占位符变量;
参考data.txt中如下二行文本:
William Stanek Engineering Williams@adatum.com 3408
wu wanqun wh wwuhn@hotmail.com 222
如果将该行文本看成一个记录,可以划分为5个字段。如果初始变量设置为 %%A,则第一次迭代:
%%A:William
%%B:Stanek;
%%C:Engineering
%%D:Williams@adatum.com
%%E:3408
第二次迭代:
%%A:wu
%%B:wanqun
%%C:wh
%%D:wwuhn@hotmail.com
%%E:222
for /f "tokens=1-5" %A in (data.txt) do @echo name:%A %B department:%C email:%D ext%E
for /f "tokens=1-5" %%A in (data.txt) do (@echo name:%%A %%B
@echo department:%%C
@echo email:%%D
@echo ext:%%E)
tokens指定要处理的字段,如果初始变量是%%A,则每一个字段是%%A,第二个字段是%%B,...
文本文件中所有的空行被忽略;
可以通过空格或通配符指定多个源文件;
如果文件名包含空格,可者想执行某条命令,可以使用usebackq选项与引号,如
for /f "tokens=3-5 usebackq" %%C in (`type "user data.txt"`) do (@echo depart:%%C email:%%D ext:%%E)
for /r c:\ %a in (*.exe) do @echo %~nxa >>exefile.txt
注意顺序,如果用下面的顺序就不行:
for /r %a c:\ in (*.exe) do @echo %~nxa >>exefile.txt