目录
1. For
for 循环命令,只要条件符合,它将多次执行同一命令。
FOR %variable IN (set) DO command [command-parameters]
%variable 指定一个单一字母可替换的参数。
(set) 指定一个或一组文件。可以使用通配符。
Command 指定对每个文件执行的命令。
command-parameters 为特定命令指定参数或命令行开关。
在批处理程序中使用FOR命令时,指定变量请使用%%variable而不要用%variable。变量名称是区分大小写的,所以%i不同于%I。
%%变量名:这个变量名可以是小写a-z或者大写A-Z,他们区分大小写,FOR会把每个读取到的值给他。
如果启用命令扩展,则会支持下列FOR命令的其他格式:
FOR有4个参数 /d /l /r /f。
a). /d 仅为目录
FOR /D %variable IN (set) DO command [command-parameters]
如果 Set (也就是上面写的 "相关文件或命令") 包含通配符(* 和 ?),将对与 Set 相匹配的每个目录(而不是指定目录中的文件组)执行指定的 Command。
他主要用于目录搜索,不会搜索文件。
@echo off
for /d %%i in (*) do @echo %%i
pause
把他保存放在C盘根目录执行,就会把C盘目录下的全部目录名字打印出来,而文件名字一个也不显示。
在来一个,比如我们要把当前路径下文件夹的名字只有1-3个字母的打出来
@echo off
for /d %%i in (???) do @echo %%i
pause
这样的话如果你当前目录下有目录名字只有1-3个字母的,就会显示出来,没有就不显示。
b). /R 递归
FOR /R [[drive:]path] %variable IN (set) DO command [command-parameters]
检查以 [drive:]path 为根的目录树,指向每个目录中的 FOR 语句。如果在 /R 后没有指定目录规范,则使用当前目录。如果集仅为一个单点(.)字符,则枚举该目录树。
他可以把当前或者你指定路径下的文件名字全部读取,注意是文件名字。
@echo off
for /r c: %%i in (*.exe) do @echo %%i
pause
这个BAT保存到D盘随便哪里然后执行,就会看到,他把C盘根目录,和每个目录的子目录下面全部的EXE文件都列出来了,这里的c:就是目录了。
@echo off
for /r %%i in (*.exe) do @echo %%i
pause
参数不一样了,这个命令前面没加那个C:也就是搜索路径,这样他就会以当前目录为搜索路径,比如你这个BAT你把他放在d:目录下执行,那么他就会把D:目录和他下面的子目录的全部EXE文件列出来。
%%a:文件完整信息
%%~da:保留文件所在驱动器信息
%%~pa:保留文件所在路径信息
%%~na:保留文件名信息
%%~xa:保留文件后缀信息
%%~za:保留文件大小信息
%%~ta:保留文件修改时间信息
%%~dpa:保留文件所在驱动器和所在路径信息
%%~nxa:保留文件名及后缀信息
%%~pnxa:保留文件所在路径及文件名和后缀信息
%%~dpna:保留文件驱动器、路径、文件名信息
%%~dpnxa:保留文件驱动器、路径、文件名、后缀信息
c). /L 迭代数值范围
FOR /L %variable IN (start,step,end) DO command [command-parameters]
该集表示以增量形式从开始到结束的一个数字序列。
使用迭代变量设置起始值 (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
for /l %%i in (1,1,5) do @echo %%i
pause
保存执行看效果,他会打印从1 2 3 4 5 这样5个数字。(1,1,5)这个参数也就是表示从1开始每次加1直到5终止。
例2:
@echo off
for /l %%i in (1,1,5) do start cmd
pause
执行后会多出5个CMD窗口。原因在于“start”是开启cmd窗口命令。当然也可以把那个start cmd改成md %%i,这样就会建立指定个目录了。
d) /f 用法多样
含有/F的for有很大的用处,在批处理中使用的最多,用法如下:
格式:
FOR /F ["options"] %%i IN (file) DO command
FOR /F ["options"] %%i IN ("string") DO command --注意双引号
FOR /F ["options"] %%i IN (‘command’) DO command --注意单引号,cmmand命令不需再用””
这是FOR最常用的,也是最强的命令,主要用来处理文件和一些命令的输出结果。
file代表一个或多个文件
string 代表字符串
command代表命令
["options"] 可选
例如读取注册表CLASSPATH项的值:
@echo off
Set CLASSPATH=
FOR /f “tokens=3” %%i IN (‘reg query “HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment” /v CLASSPATH’) DO (SET CLASSPATH=%%i)
Echo %CLASSPATH%
Pause>nul
对于
FOR /F %%i IN (file) DO command
file为文件名,按照官方的说法是,for会依次将file中的文件打开,并且在进行到下一个文件之前将每个文件读取到内存,按照每一行分成一个一个的元素,忽略空白的行,看个例子。
假如文件a.txt中有如下内容:
第1行第1列第1行第2列第1行第3列
第2行第1列第2行第2列第2行第3列
第3行第1列第3行第2列第3行第3列
想显示a.txt中的内容,for命令如下:
for /f %%i in (a.txt) do echo %%i
还是先从括号执行,因为含有参数/f,所以for会先打开a.txt,然后读出a.txt里面的所有内容,把它作为一个集合,并且以每一行作为一个元素,所以会产生这样的集合。
{"第1行第1列第1行第2列第1行第3列", //第一个元素
"第2行第1列第2行第2列第2行第3列", //第二个元素
"第3行第1列第3行第2列第3行第3列"} //第三个元素
集合中只有3个元素,同样用%%i依次代替每个元素,然后执行do后面的命令。
具体过程:
用%%i代替"第1行第1列第1行第2列第1行第3列",执行do后面的echo %%i,显示"第1行第1列第1行第2列第1行第3列",
用%%i代替"第2行第1列第2行第2列第2行第3列",执行echo %%i,显示"第2行第1列第2行第2列第2行第3列",
依次,直到每个元素都代替完为止。
为了加强理解/f的作用,请执行一下两个命令,对比即可明白:
for /f %%i in (a.txt) do echo %%i
这个会显示a.txt里面的内容,因为/f的作用,会读出a.txt中的内容。
for %%i in (a.txt) do echo %%i
而这个只会显示a.txt这个名字,并不会读取其中的内容。
假如文件a.txt中有如下内容:
第1行第1列 第1行第2列 第1行第3列
第2行第1列 第2行第2列 第2行第3列
第3行第1列 第3行第2列 第3行第3列
想显示a.txt中的内容,for命令依旧如下:
for /f %%i in (a.txt) do echo %%i
那么就无法将所有内容显示出来,显示结果如下:
第1行第1列
第2行第1列
第3行第1列
因为命令默认以空格和TAB为分隔符,所以它遇到分隔符之后,默认只取第一个,将分隔符后面的都丢掉。
如果我们还想把每一行再分解更小的内容,该怎么办呢? for命令还为我们提供了更详细的参数,使我们将每一行分为更小的元素成为可能。
1). delims和tokens
delims 用来告诉for每一行应该拿什么作为分隔符,默认的分隔符是空格和tab键
比如,还是上面的文件,我们执行下面的命令:
for /f "delims= " %%i in (a.txt) do echo %%i
显示的结果是:
第1行第1列
第2行第1列
第3行第1列
因为这里有delims参数,=后面有一个空格,意思是再将每个元素以空格分割,默认是只取分割之后的第一个元素。
执行过程是:
将第一个元素"第1行第1列 第1行第2列 第1行第3列"分成三个元素:"第1行第1列" "第1行第2列" "第1行第3列",它默认只取第一个,即"第1行第1列",然后执行do后面的命令,依次类推。
但是这样还是有局限的,如果我们想要每一行的第二列元素,那又如何呢?
这时候,tokens能做到。
它的作用就是当你通过delims将每一行分为更小的元素时,由它来控制要取哪一个或哪几个。
还是上面的例子,执行如下命令:
for /f "tokens=2 delims= " %%i in (a.txt) do echo %%i
执行结果:
第1行第2列
第2行第2列
第3行第2列
如果要显示第三列,那就换成tokens=3。
同时tokens支持通配符*,以及限定范围。
如果要显示第二列和第三列,则换成tokens=2,3或tokens=2-3,如果还有更多的则为:tokens=2-10之类的。
此时的命令为:
for /f "tokens=2,3 delims= " %%i in (a.txt) do echo %%i %%j
怎么多出一个%%j?这是因为你的tokens后面要取每一行的两列,用%%i来替换第二列,用%%j来替换第三列。并且必须是按照英文字母顺序排列的,%%j不能换成%%k,因为i后面是j。
执行结果为:
第1行第2列 第1行第3列
第2行第2列 第2行第3列
第3行第2列 第3行第3列
对以通配符*,就是把这一行全部或者这一行的剩余部分当作一个元素了。
比如:
for /f "tokens=* delims= " %%i in (a.txt) do echo %%i
执行结果为:
第1行第1列 第1行第2列 第1行第3列
第2行第1列 第2行第2列 第2行第3列
第3行第1列 第3行第2列 第3行第3列
通过这种方式,可以读取含有空格的一整行内容。
再如:
for /f "tokens=2,* delims= " %%i in (a.txt) do echo %%i %%j
执行结果为:
第1行第2列 第1行第3列
第2行第2列 第2行第3列
第3行第2列 第3行第3列
用%%i代替第二列,用%%j代替剩余的所有
2). skip和eol
这俩个简单,skip就是要忽略文件的前多少行,而eol用来指定当一行以什么符号开始时,就忽略它。
如
第1行第1列 第1行第2列 第1行第3列
第2行第1列 第2行第2列 第2行第3列
第3行第1列 第3行第2列 第3行第3列
,第4行第1列 第4行第2列 第4行第3列
比如:
for /f "tokens=* delims= skip=2 eol=," %%i in (a.txt) do echo %%i
执行结果为:
第3行第1列 第3行第2列 第3行第3列
3). usebackq
usebackq就是反转的意思,他把字符串(“out.txt”)当做文件,或者把(‘command’)当做字符串。
例如:
for /f "usebackq tokens=* delims= " %%i in (“a.txt”) do echo %%i
执行结果为:
第1行第1列 第1行第2列 第1行第3列
第2行第1列 第2行第2列 第2行第3列
第3行第1列 第3行第2列 第3行第3列
如果不加usebackq,则”a.txt”会被当成字符串,执行结果为:
a.txt
又例如:
for /f "usebackq tokens=*" %%i in (‘echo helloworld!’) do echo %%i
输出结果为:
echo helloworld!
echo helloworld!被当做字符串处理。如果不加usebackq,则输出结果为:
helloworld!
他执行的是echo helloworld!命令。
2. Goto
goto 批处理文件运行到这里将跳到goto所指定的标号(标号即label,标号用“:”后跟标准字符串来定义)处,goto语句一般与if配合使用,根据不同的条件来执行不同的命令组。
标号用“:字符串”来定义,标号所在行不被执行。指定跳转到标签,找到标签后,程序将处理从下一行开始的命令。
语法:
goto label (label是参数,指定所要转向的批处理程序中的行。)
例如:
@echo off
goto end
:end
echo this is the end
pause>nul
标签的名字可以随便起,但是最好是有意义的字母,字母前加个‘:’用来表示这个字母是标签,goto命令就是根据这个‘:’来寻找下一步跳到到那里。