控制结构
1.
如何定义行号?
可以定义任意长度的
label
并且中间允许有空格,但是
MS-DOS
只区分其中的前
8
个字符,以冒号开头的脚本文件行不被处理。
行号同样不区分大小写。行号的冒号前面可以有空白符号。
2.
如何使用
GOTO
语句?
<label>
一般为所定义的行号,如果命令扩展被允许(
default
)也可以用命令跳转到文件末尾:
:EOF
不区分大小写
如果命令找不到需要跳转的行好位置,则显示:
3.
如何使用
For
循环语句?
FOR {%<var>|%%<var>} IN (<set>) DO <command>
FOR
语句可以在命令行和脚本文件中使用,在脚本文件中使用,变量定义和引用用
%%
;在命令行中使用,变量定义和引用用
%
。变量名是大小写敏感的,并且可以用除了
0
到
9
任意的单个字符(不包含元符号),这点比较特殊。
DO
后面是需要执行的语句,
循环变量的定义域在
DO
子句中。
<set>
有多种形式考虑:
l
可以是字符串的集合,中间用空白符分割:
<string> <string> <string>
l
可以是通配符展开的
文件名或路径名
另外文件名还可以是特殊的字符
,
当前目录
(.)
和上级目录(
..
)
这些内容之间可以通过分隔符分开,分隔符是空白、分号、逗号、双引号,注意引号本身会传递到循环变量中去,
而分号和逗号则不会,另外如果其他三种分隔符出现在双引号中,他们会被传递到循环变量中去。
可以对不同种类的
<set>
值进行遍历:
l
对字符串遍历
FOR %%<var> IN (<string-set>) DO <command>
l
对文件进行遍历
FOR %%<var> IN (<file-path-name-wildcard>) DO <command>
下面的命令需要命令扩展打开
l
对目录进行遍历
FOR /D %%<var> IN (<dir-path-name-wildcard>) DO <command>
l
递归遍历文件树
FOR /R [[<driver>:]<path>] %%<var> IN (<set>) DO <command>
如果没有目录指定,则默认从当前目录开始。
l
进行步长型循环
FOR /L %%<var> IN (<start> <step> <end>) DO <command>
其中
<start> <step> <end>
是整数(其他数会取整),无法解释的字符串认为是
0
,可以递增或递减。
l
文件遍历和解析
FOR /F ["<parsing-keywords>"] %%<var> IN (<set>) DO <command>
其中
<parsing-keywords>
的形式(大小写不敏感)如下:
eof=<c> #<c>
是一个字符的行结束符,默认是
newline
字符,行结束符后面认为是注释
skip=<N> #<N>
是从行首跳过的行数,默认是
0
delims=<xxx> #<xxx>
是记录字段的分隔符集,默认是空格和
<tab>
,覆盖默认会提取空白
tokens=[{<X>,|<M>-<N>,}…][*] #
指定提取的记录字段,默认是
1
,最后的
*
代表剩余字段
#
剩余字段不会去除分隔符,但是去除注释
usebackq #
使用
back quotation
作为命令的引用符(见
<set>
的格式),默认是不使用
如果不使用
usebackq
选项,
<set>
的形式:
<file-set> #no quotation
“<literal-string>” #double quotation
‘<command>’ #single quotation
如果使用
useback
选项,
<set>
的形式:
“<file-set>” # double quotation
‘<literal-string>’ #single quotation
`<command>` #back quotation
关于隐含变量,只需指定首个变量的字母,其它按顺序依次排列,最多可以定义
26
个变量。(大小写敏感)
FOR
语句中的变量名同样可以展开为:
%%~[{f|d|a|z|s|n|x|t|p}][$<var>:]<c>
4.
IF
条件语句的语法格式为:
IF [NOT] <condition> <command> [ELSE <command>]
其中
NOT
表示条件真值去反。
利用不同的
<condition>,
我们可以判断
l
ERROR-LEVEL:
等于或大于
<n>
的错误发生时为真
l
字符串相等
字符串相等,不需要用引号环绕
l
文件存在
下面需要命令扩展打开
l
字符串比较
[/I] <string> <comparator> <string>
/I
选项打开则比较是
case-insensitive,
如果都是数字作比较,则转为用数值比较,只能比较整数,比较浮点数则采用字符串比较法。
比较操作符
(
大小写不敏感
)
包括:
EQU (
等于
)
、
LSS (
小于
)
、
GTR (
大于
)
、
GEQ(
大于等于
)
、
LEQ(
小于等于
)
、
NEQ(
不等)
l
命令行扩展版本
当命令扩展版本号大于或等于
<n>
时为真,该值最低版本为
1
l
变量定义
如果变量的定义存在则为真
则自动增加一下变量定义
-
%ERRORLEVEL%
定义为当前的即上次命令行执行产生的
errorlevel
(一定有定义)
-
%CMDCMDLINE%
定义为上次传递给命令解释器
(cmd.exe)
的未经处理的原始命令行。
(如果
%CMDCMDLINE%
未被定义,否则不影响原始值)
-
%CMDEXTVERSION%
定义为当前命令扩展的版本号(如果
% CMDEXTVERSION %
未被定义,否则不影响原始值)
如果使用
ELSE
语句应当用以下形式,因为必须用复合语句或
newline
来结束
<command>:
IF [NOT] <condition> (
<command>
) ELSE IF (
<command>
) ELSE (
<command>
)
或者:
IF [NOT] <condition> (<command>) ELSE (<command>)
5.
CHOICE
选项分支命令,格式如下:
CHOICE [/c [<choices>]] [/n] [/cs] [/t <timeout> /d <default>] [/m <msg>]
其中
/c
选项指定用户的选择键,默认是
yn
,其显示为:
/cs
指定大小写敏感选择,默认不敏感,如果不敏感则提示选择键都采用大写字符。
/n
隐藏键提示信息。
/t
指定超时时间
(second)
,根据版本不同可能会显示递减的计时数字,默认不超时。
/d
超时后的默认选项。
/m
指定提示信息,显示在选择键提示前面。
注意,该命令不是所有的命令解释器都支持。
该命令返回用户选择键的序号
(
从
1
开始
)
作为
errorlevel
的值
,
可由
IF
语句判断。
6.
如何定义组合语句
?
在上述控制语句中,如
DO
、
IF/ELSE
结构中,经常会嵌入一段代码,由几条语句构成,这时候需要定义组合语句,甚至在有些结构中,例如
IF/ELSE
,即使只有一条语句也写成组合语句的形式。组合语句定义如下:
特别是
<command-lines>
为空,即可以定义空语句。
多个命令在一行时需要用
&
来分隔。