Windows批处理编程入门
2010-08-03 21:42:57 阿炯

使用批处理文件
使用批处理文件(也被称为批处理程序或脚本),可以简化日常或重复性任务。批处理文件是无格式的文本文件,它包含一条或多条命令。它的文件扩展名为 .bat 或 .cmd。在命令提示下键入批处理文件的名称,cmd.exe 就会按照该文件中各个命令出现的顺序来逐个运行它们。
可以在批处理文件中包含任何命令。某些命令,比如 for、goto 和 if 命令等,它们允许您对批处理文件中的命令作条件处理。例如,if 命令根据条件语句的结果来执行命令。其他命令允许您控制输入输出以及调用其他批处理文件。
如果没有错误,大多数应用程序会返回标准错误代码 0;如果出错,则返回 1(或更大的值)。请参考应用程序的帮助文档以确定某个错误代码的含义。
有关批处理文件操作的详细信息,请参阅以下主题:

使用批处理参数
使用筛选器
使用命令重定向操作符

有关在批处理文件中使用的命令的信息,请单击以下的命令:
Call
Echo
Endlocal
For
Goto
If
Pause
Rem
Setlocal
Shift

使用批处理参数
可以在批处理文件内的任何地方使用批处理参数,以提取有关环境设置的信息。
cmd.exe 提供批处理参数扩展变量(%0 到 %9)。当在批处理文件中使用批处理参数时,%0 将由批处理文件名替换,而 %1 到 %9 将由在命令行键入的相应参数替换。要访问大于 %9 的参数,必须使用 shift 命令。有关 Shift 命令的详细信息,请参阅 Shift。%* 批处理参数是所有参数(不包括 %0)可引用的通配符,这些参数传递到批处理文件中。
例如,要将 Folder1 中的内容复制到 Folder2,其中 %1 和 %2 将分别由值 Folder1 和 Folder2 替换,请在批处理文件 Mybatch.bat 中键入如下内容:
xcopy %1\*.* %2

要运行该文件,请键入:
mybatch.bat C:\folder1 D:\folder2

这与在批处理文件中键入如下内容是等效的:
xcopy C:\folder1 \*.* D:\folder2

也可以在批处理参数中使用编辑符。编辑符使用当前的驱动器和目录信息将批处理参数扩展为部分或完整的文件或目录名。要使用编辑符,请键入百分号 (%) 字符,后面是波形符号 (~) 字符,然后键入合适的编辑符(即 %~modifier)。

下表列出了可在扩展中使用的编辑符。
编辑符     说明
%~1     扩展 %1 并删除任何引号 ("")。
%~f1     将 %1 扩展到完全合格的路径名。
%~d1     将 %1 扩展到驱动器盘符。
%~p1     将 %1 扩展到路径。
%~n1     将 %1 扩展到文件名。
%~x1     将 %1 扩展到文件扩展名。
%~s1     扩展的路径仅包含短名称。
%~a1     将 %1 扩展到文件属性。
%~t1     将 %1 扩展到文件日期/时间。
%~z1     将 %1 扩展到文件大小。
%~$PATH:1     搜索 PATH 环境变量中列出的目录,并将 %1 扩展到第一个找到的目录的完全合格名称。如果没有定义环境变量名称,或没有找到文件,则此编辑符扩展成空字符串。

下表列出了可用于获取复杂结果的编辑符和限定符的可能组合情况:
编辑符     说明
%~dp1     将 %1 扩展到驱动器盘符和路径。
%~nx1     将 %1 扩展到文件名和扩展名。
%~dp$PATH:1     在 PATH 环境变量列出的目录中搜索 %1,并扩展到第一个找到的目录的驱动器盘符和路径。
%~ftza1     将 %1 扩展到类似 dir 的输出行。

注意
* 在上面的例子中,可以使用其它批处理参数替换 %1 和 PATH。

%* 编辑符是唯一可代表在批处理文件中传递的所有参数的编辑符。不能将该编辑符与 %~ 编辑符组合使用。%~ 语法必须通过有效的参数值来终止。
不能以与使用环境变量相同的方式使用批处理参数。不能搜索或替换值,或检查子字符串。然而,可以将参数分配给环境变量,然后使用该环境变量。

使用筛选器
与命令重新定向管道符 (|) 联合使用,命令筛选器是这样一个命令,该命令包含在可读取命令的输入、可转换输入并写入输出的命令里。筛选器命令可以帮助您排序、查看和选择部分命令输出。
筛选器命令可以划分、重排以及提取通过的部分信息操作。下表列出 Windows XP 中可用的筛选器命令。
命令     说明
more     在一个命令提示符窗口中每次显示一个文件的内容或一个命令的输出。
find     在文件和命令输出中搜索您所指定的字符。
sort     按字母顺序排列文件和命令输出。

要将输入从文件发送到筛选器命令,请使用小于号 (<)。如果要使筛选器命令从其它命令获得输入,请使用管道 (|)。
使用 more 命令

more 命令在一个命令提示符窗口中每次显示一个文件的内容或一个命令的输出。例如,要在一个命令提示窗口中每次显示一个名为 List.txt 的文件的内容,请键入:
more < list.txt

出现一个包含信息的命令提示符窗口,然后在命令提示符窗口底部出现 -- More -- 提示。要继续前进到下一个命令提示符窗口,请在键盘上按任意键(除 PAUSE 之外)。要停止命令且不查看详细信息,请按 CTRL+C 键。
使用产生多个输出命令提示符窗口的命令时,可以使用 more 命令。例如,假定要查看硬盘上的目录树。如果命令提示符窗口不能将目录在一屏内全部显示出来,请使用带管道 (|) 和 more 命令的 tree 命令,如下例所示:
tree c:\ | more

出现由 tree 命令产生的第一个输出命令提示符窗口,后面跟着 -- More -- 提示。输出暂停,直到用户按键盘上的任意键为止(PAUSE 键除外)。

使用 find 命令
find 命令在文件中搜索指定的字符串或文字。cmd.exe 显示与在命令提示符窗口中指定的字符串或文字相匹配的所有行。可以把 find 命令用作筛选器命令,也可以用作标准的 Windows XP 命令。有关如何将 find 用作标准命令的详细信息,请参阅 Find。
要将 find 命令用作筛选器命令,必须将小于号 (<) 和要搜索的字符串或文本包括在内。默认情况下,find 搜索将区分大小写。例如,下面的命令查找文件 Trade.txt 中所有的“Pacific Rim”字符串:
find "Pacific Rim" < trade.txt

输出不包括出现“pacific rim”的任何字符串。输出只包括所有首字母大写的“Pacific Rim”字符串。
要保存 find 命令的输出而不是在命令提示符窗口显示输出,请键入大于号 (>) 和要存储输出的文件的名称。例如,下面的命令查找文件 Trade.txt 中存在的“Pacific Rim”字符串,并将结果保存在 Nwtrade.txt 文件中:
find "Pacific Rim" nwtrade.txt

使用 sort 命令
sort 命令按字母顺序排列文本文件或命令的输出。例如,下列命令对名为 List.txt 的文件的内容进行排序,并在命令提示符窗口中显示排序结果:
sort < list.txt

在此范例中,sort 命令对 List.txt 文件的行按字母列表进行排序并显示结果,但不更改文件。要保存 sort 命令的输出而不是显示输出,请键入大于号 (>) 和文件名。例如,以下命令对 List.txt 文件的行按字母顺序排序,并将结果存储到 Alphlist.txt 文件中:
sort alphlist.txt

要对命令输出进行排序,请键入该命令,键入管道 (|),然后键入 sort(即,command | sort)。例如,下列命令对包括字符串“Jones”(即,find 命令输出)的行按字母顺序进行排序:
find "Jones" maillst.txt | sort

使用命令重定向操作符 (Redirection Operators)
可以使用重定向操作符将命令输入和输出数据流从默认位置重定向到不同的位置。输入或输出数据流的位置即为句柄。下表列出了可用于将命令输入和输出数据流进行重定向的操作符。
重定向操作符     说明
>     将命令输出写入到文件或设备(例如打印机)中,而不是写在命令提示符窗口中。
<     从文件中而不是从键盘中读入命令输入。
>>     将命令输出添加到文件末尾而不删除文件中的信息。
>&     将一个句柄的输出写入到另一个句柄的输入中。
<&     从一个句柄读取输入并将其写入到另一个句柄输出中。
|     从一个命令中读取输出并将其写入另一个命令的输入中。也称作管道。

默认情况下,可以从键盘将命令输入(即 STDIN 句柄)发送到 cmd.exe,然后由 cmd.exe 将命令输出(即 STDOUT 句柄)发送到命令提示符窗口。

下表将列出可用的句柄。
句柄     句柄的数字代号    说明
STDIN     0     键盘输入
STDOUT     1     输出到命令提示符窗口
STDERR     2    错误输出到命令提示符窗口
UNDEFINED     3-9    这些句柄由应用程序和各个具体工具单独定义。

数字 0 到 9 代表前 10 个句柄。可以使用命令 cmd.exe 运行程序并将前 10 个句柄中的任何一个重定向到该程序。要指定想使用的句柄,可在重定向操作符前面键入该句柄的数字。如果未定义句柄,则默认的 重定向输出操作符是 1。键入 > 或 < 操作符之后,必须指定要读取或写入数据的位置。可以指定文件名或另一个现有的句柄。
要指定重定向到现有句柄,请使用与 (&) 字符,后面接要重定向的句柄号(例如 &句柄#)。例如,下面的命令可以将句柄 2(即 STDERR)重定向到句柄 1(即 STDOUT):
1<&2
复制句柄

重定向操作符 & 可以将输出或输入从一个句柄复制到另一个指定的句柄。例如,要将 dir 输出发送到 File.txt 并将错误输出发送到 File.txt,请键入:
dir>c:\file.txt 2>&1

复制句柄时,可以复制该句柄原状态的所有特性。例如,如果一个句柄具有只读访问的属性,则该句柄的所有副本都具有只读访问属性。不能将一个具有只读访问属性的句柄复制为另一个具有只写访问属性的句柄。

重定向命令输出 (<)
要从键盘或设备重定向命令输出,请使用 < 操作符。例如,要从 File.txt 得到 sort 命令的命令输入,请键入:
sort
File.txt 的内容将以字母顺序列表的方式显示在命令提示符窗口中。
< 操作符可以打开具有只读访问的指定文件名。所以,不能使用该操作符向文件中写入信息。例如,如果以 <&2 启动程序,则所有试图读取句柄 0 的操作都将失败,因为句柄 2 最初是以只读访问打开的。

注意
* 0 是 的默认句柄。

重定向命令输出 (>)
几乎所有的命令都将输出发送到命令提示符窗口。即使将输出发送到驱动器或打印机的命令也会在命令提示符窗口显示消息和提示。
要将命令输出从命令提示符窗口重定向到文件或设备,请使用 > 操作符。可以在许多命令中使用该操作符。例如,要将 dir 输出重定向到 Dirlist.txt,请键入:
dir>dirlist.txt

如果 Dirlist.txt 不存在,cmd.exe 将创建该文件。如果 Dirlist.txt 存在,cmd.exe 将使用 dir 命令的输出替换文件中的信息。要运行 netsh routing dump 命令,然后将命令输出发送到 Route.cfg,请键入:
netsh routing dump>c:\route.cfg

> 操作符可以打开具有只写访问属性的指定文件。所以,不能使用该操作符读取文件。例如,如果使用重定向 >&0 启动程序,则所有试图写入句柄 1 的操作都将失败,因为句柄 0 最初是以只读访问大开的。

注意
* 1 是 > 重定向输出操作符的默认句柄。

使用 <& 操作符重定向输入和复制
要使用重定向输入操作符 <&,指定的文件必须已经存在。如果输入文件存在,cmd.exe 将以只读方式打开该文件,然后将文件中作为输入的字符发送到此命令(如同从键盘输入一样)。如果指定了句柄,cmd.exe 将指定的句柄复制到系统现有的句柄中。
例如,要以句柄 0 输入读取(即 STDIN)的方式打开 File.txt,请键入:

要打开 File.txt,并在内容分类后将输出发送到命令提示符窗口(即 STDOUT),请键入:
sort
要查找 File.txt,然后将句柄 1(即 STDOUT)和句柄 2(即 STDERR)重定向到 Search.txt,请键入:
findfile file.txt>search.txt 2<&1

要以句柄 0 输入读取(即 STDIN)的方式复制用户定义句柄 3,请键入:
<&3
使用 >& 操作符重定向输出和复制

如果将输出重定向到文件且指定了现有的文件名,cmd.exe 将以只写方式打开文件并覆盖该文件内容。如果指定了句柄,cmd.exe 将文件复制到现有句柄中。要将用户定义句柄 3 复制到句柄 1,请键入:
>&3

要将包括句柄 2(即 STDERR)的所有输出从 ipconfig 命令重定向到句柄 1(即 STDOUT),然后将输出重定向到 Output.log,请键入:
ipconfig.exe>>output.log 2>&1

使用 >> 重定向操作符追加输出
要从命令中将输出添加到文件末尾而不丢失文件中已存在的任何信息,请使用两个连续的大于号(即 >>)。例如,下面的命令可以将由 dir 命令生成的目录列表追加到 Dirlist.txt 文件:
dir>>dirlist.txt

要将 netstat 命令的输出追加到 Tcpinfo.txt 的末尾,请键入:
netstat>>tcpinfo.txt

使用管道操作符 (|)
管道操作符 (|) 可以提取一个命令的输出(默认情况下是 STDOUT),然后将其导入另一个命令的输入中(默认情况下是 STDIN)。例如,下面的命令将对目录分类:
dir | sort

在本例中,将同时启动两个命令,但随后 sort 命令会暂停,直到它接收到 dir 命令的输出为止。sort 命令使用 dir 命令的输出作为输入,然后将输出发送到句柄 1(即 STDOUT)。

合并带重定向操作符的命令
可以通过合并带有其它命令和文件名的筛选器命令创建自定义命令。例如,可以使用以下命令存储包含“LOG”字符串的文件名:
dir /b | find "LOG" > loglist.txt

dir 命令的输出通过 find 筛选器命令发送。包含字符串 "LOG" 的文件名作为文件名列表(例如,NetshConfig.log、Logdat.svd 和 Mylog.bat)存储在文件 Loglist.txt 中。
要在相同命令中使用多个筛选器,请使用管道 (|) 分隔筛选器。例如,下面的命令将搜索 C 盘上的每个目录以查找包含 "LOG" 字符串的文件名,并且在命令提示符窗口中每次显示一屏:
dir c:\ /s /b | find "LOG" | more

利用管道 (|) 可以将 cmd.exe 导向为通过 find 筛选器命令发送 dir 命令输出。find 命令只选择包含字符串 "LOG" 的文件名。more 命令可以显示由 find 命令选择的文件名(在命令提示符窗口中每次显示一屏)。有关筛选器命令的详细信息,请参阅筛选器命令。

Call
从一个批处理程序调用另一个批处理程序,并且不终止父批处理程序。call 命令接受用作调用目标的标签。如果在脚本或批处理文件外使用 Call,它将不会在命令行起作用。
语法
call [[Drive:][Path] FileName [BatchParameters]] [:label [arguments]]

参数
[Drive:}[Path] FileName
指定要调用的批处理程序的位置和名称。filename 参数必须具有 .bat 或 .cmd 扩展名。
BatchParameters
指定批处理程序所需的任何命令行信息,包括命令行选项、文件名、批处理参数(从 %0 到 %9)或变量(例如,%baud%)。
:label
指定批处理程序要跳转到的标签。使用带有该参数的 call 命令可以创建新的批处理文件上下文,并将控制权交给指定标签后的语句。当首次遇到该批处理文件的末尾时(在跳转到标签后),控制权将交还给 CALL 语句后的语句。第二次遇到批处理文件的末尾,批脚本将被退出。对于可允许您从批处理脚本返回的 goto :eof 命令扩展,要了解关于它的说明,请参阅“”。
arguments
对于以 :label 打头的批处理程序,指定要传送给其新实例的命令行信息,包括命令行选项、文件名、批处理参数(从 %1 到 %9)或者变量(比如 %baud%)。
/?
在命令提示符显示帮助。

注释
* 使用批处理参数
批处理参数可以含有传送给批处理程序的任何信息,包括命令行选项、文件名、批处理参数(从 %1 到 %9)或者变量(例如,%baud%)。有关批处理参数的详细信息,请参阅“”。
* 使用管道和重定向符号
不要在 call 命令中使用管道和重定向符号。
* 发出递归调用
可以创建调用自身的批处理程序,但是,必须提供退出条件。否则,父和子批处理程序可以无限循环。
* 使用命令扩展
如果启用命令扩展(即默认情况下),call 将接受 label 参数作为调用目标。正确语法如下:
call :label arguments
有关启用和禁用命令扩展的详细信息,请参阅“”中的 cmd。

范例
要从其他批处理程序运行 Checknew.bat 程序,请在父批处理程序中键入以下命令:
call checknew

如果父批处理程序接受两个批处理参数并且希望它将这些参数传递给 Checknew.bat,则可以在父批处理程序中使用以下命令:
call checknew %1 %2

回显
打开或关闭请求回显功能,或显示消息。如果没有任何参数,echo 命令将显示当前回显设置。

语法
echo [{on|off}] [message]

参数
{on | off
指定是否打开命令回显功能。
message
指定要在屏幕上显示的文本。
/?
在命令提示符显示帮助。

注释
* 当回显关闭时可以使用 echo message 命令。要显示几行长的消息而不显示其他命令,可以在批处理程序的 echo off 命令后包含几个 echo message 命令。
* 如果使用 echo off,屏幕上就不会出现命令提示符。要显示命令提示符,请键入 echo on。
* 要避免回显某行,请在批处理程序中的命令前面插入 at 符号 (@)。
* 要在屏幕上回显空白行,请键入:echo
* 当使用 echo 命令时,要显示管道 (|) 或重定向字符(),请在管道 (|) 或重定向字符(例如,^>、^< 或 ^|)的前面使用脱字符 (^)。如果需要使用脱字符 (^),请键入两个脱字符 (^^)。

范例
以下范例显示的批处理程序包含前后各有一个空行的三行消息:
echo off
echo.
echo This batch program
echo formats and checks
echo new disks
echo.

如果要关闭回显并且不需要回显 echo 命令,请在命令之前包含 at 符号 (@),如下所示:
@echo off

在相同命令行上可以使用 if 和 echo 命令,如下所示:例如:
if exist *.rpt echo The report has arrived.
XOX

Endlocal
结束批处理文件中环境更改的本地化,将环境变量还原为匹配 setlocal 命令前的值。

语法
endlocal

参数
/?
在命令提示符显示帮助。

注释
* 必须在脚本或批处理文件中使用 endlocal。如果在脚本或批处理文件之外使用 endlocal,则该命令无效。
* 在批处理文件的结尾处有一个隐含的 endlocal 命令。
* 通过启用命令扩展名(即,默认值),endlocal 命令将命令扩展名的状态(即,已启用或已禁用)还原到执行匹配 setlocal 命令之前的状态。有关启用和禁用命令扩展名的详细信息,请参阅“”中的 cmd。

范例
在批处理文件中可以本地化环境变量。例如:
@echo off
rem This program starts the superapp batch program on the network,
rem directs the output to a file, and displays the file
rem in Notepad.
setlocal
path=g:\programs\superapp;%path%
call superapp>c:\superapp.out
endlocal
start notepad c:\superapp.out

For
对一组文件中的每个文件运行指定的命令。

语法
for {%variable|%%variable} in (set) do command [ CommandLineOptions]

参数
{%variable|%%variable}
必需。代表可替换的参数。使用 %variable 通过命令提示符执行 for 命令。使用 %%variable 在批处理文件中执行 for 命令。变量要区分大小写,并且必须用 Alpha 值表示,例如,%A、%B 或 %C。
(set)
必需。指定要用指定命令处理的一个或多个文件、目录、数值范围以及文本字符串。需要括号。
command
必需。指定要对包括在指定 (set) 中的每个文件、目录、数值范围以及文本字符串所执行的命令。
CommandLineOptions
指定要通过指定命令使用的任何命令行选项。
/?
在命令提示符显示帮助。

注释
* 使用 for
可以在批处理文件中或直接从命令提示符使用 for 命令。
* 使用批处理参数
下列属性适用于 for 命令:
o for 命令使用指定 set 中的每个文本字符串替换 %variable 或 %%variable,直到 command 处理所有文件为止。
o 记住,for variable名是区分大小写、全局的,并且每次总共不超过 52 个是活动的。
o 要避免批处理参数从 %0 到 %9 混淆,对 variable 可以使用除数字 0 到 9 之外的任何字符。对于简单的批处理文件,单个字符即可奏效,例如 %%f。
o 在复杂的批处理文件中可以使用 variable 的多个值来区分不同的可替换变量。
* 显示一组文件
set 参数可以代表单个或多个文件组。可以使用通配符(即,*
和 ?)指定文件组。以下为有效文件组:
(*.doc)
(*.doc *.txt *.me)
(jan*.doc jan*.rpt feb*.doc feb*.rpt)
(ar??1991.* ap??1991.*)
在使用 for 命令时,set 中的第一个值代替 %variable 或 %%variable,然后由指定的命令处理该值。这一直会继续下去,直到处理完与 set 值相对应的所有文件(或文件组)为止。
* 使用 in 和 do 关键字
In 和 do 不是参数,但必须将它们与 for 一起使用。如果省略其中任何一个关键字,就会出现错误消息。
* 使用 for 的其它形式
如果命令扩展名处于启用状态(即,默认设置),则支持 for 的下列其它形式:
o 仅为目录
如果 set 包含通配符(* 和 ?),则为匹配 set 的每个目录(而不是指定目录中的文件组)而执行指定的 command。语法是:            for /D {%% | %}variable in (set) do command [CommandLineOptions]
o 递归
进入根目录树 [Drive:]Path,在树的每个目录中执行 for 语句。如果在 /R 后没有指定目录,则假定为当前目录。如果 set 只是一个句号 (.),则只列举目录树。语法是:
for /R [[Drive :]Path] {%% | %}variable in (set) do command [CommandLineOptions]
o 重复数值范围
使用迭代变量设置起始值 (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)。语法是:
for /L {%% | %}variable in (start#,step#,end#) do command [CommandLineOptions]
o 重复和文件解析
使用文件解析过程处理命令输出、字符串和文件内容。使用迭代变量定义要检查的内容或字符串,以及使用各种 ParsingKeywords 选项进一步修改解析方式。使用 ParsingKeywords 令牌选项指定哪些令牌应该传递为迭代程序变量。注意:在没有使用令牌选项时,/F 将仅检查第一个令牌。文件解析过程包括读取输出、字符串或文件内容、分成独立的文本行及然后将每行解析成零个或更多个令牌。然后通过设置为令牌的迭代程序变量值,调用 for 循环。默认情况下,/F 传递每个文件每一行的第一个空白分隔符号。跳过空行。语法的不同点为:
for /F ["ParsingKeywords"] {%% | %}variable in (filenameset) do command [CommandLineOptions]
for /F ["ParsingKeywords"] {%% | %}variable in ("LiteralString") do command [CommandLineOptions]
for /F ["ParsingKeywords"] {%% | %}variable in ('command') do command [CommandLineOptions]

filenameset 参数指定一个或多个文件名称。在继续到 filenameset 中的下一个文件之前,每个文件都会被打开、读取和处理。要覆盖默认解析行为,指定 "ParsingKeywords"。这是一个引用字符串,它包含一个或多个关键字以指定不同的解析选项。

如果使用 usebackq 选项,请使用如下语法之一:
for /F ["usebackqParsingKeywords"] {%% | %}variable in ("filenameset") do command [CommandLineOptions]
for /F ["usebackqParsingKeywords"] {%% | %}variable in ('LiteralString') do command [CommandLineOptions]
for /F ["usebackqParsingKeywords"] {%% | %}variable in (`command`) do command [CommandLineOptions]

下表列出可以用于 ParsingKeywords 的解析关键字。
关键字     说明
eol=c     指定行尾字符(只一个字符)。
skip=n     指定在文件的开头跳过的行数。
delims=xxx     指定定界符集合。这将替换空格和制表符的默认分隔符集。
tokens=x,y,m-n     指定将哪些令牌从每行传递到每个迭代的 for 正文。结果就分配了附加变量名称。m-n 格式是一个范围,指定从 mth 到 nth 的令牌。如果 tokens=字符串中最后一个字符是星号 (*),则将分配附加的变量,并在解析的最后一个令牌后在行上接收剩余的文本。
usebackq     指定可以使用引号引用 filenameset 中的文件名称,将后面带有引号的字符串作为一个命令执行,而带有单引号的字符串是文字字符串命令。
o 变量替换
已经增强了 for 变量引用的替换修改程序。下表列出可选语法(对于任意变量 I)。
带有修改程序的变量     说明
%~I     展开删除任何前后引号 ("") 的 %I。
%~fI     将 %I 展开到完全合格的路径名。
%~dI     只将 %I 展开到驱动器号。
%~pI     只将 %I 展开到路径。
%~nI     只将 %I 展开到文件名。
%~xI     只将 %I 展开到文件扩展名。
%~sI     展开路径以只包含短名称。
%~aI     将 %I 展开到文件的文件属性。
%~tI     将 %I 展开到文件的日期和时间。
%~zI     将 %I 展开到文件大小。
%~$PATH:I     搜索 PATH 环境变量所列出的目录,并将 %I 展开到第一个找到的完全合格的名称。如果没有定义环境变量名称,或搜索没有找到文件,则此修改程序扩展成空字符串。

下表列出可用来获得综合结果的修改程序组合。
变量(使用组合的修改程序)     说明
%~dpI     只将 %I 展开到驱动器号和路径。
%~nxI     只将 %I 展开到文件名和扩展名。
%~fsI     将 %I 展开到只包含短名称的完整路径名。
%~dp$PATH:I     在 PATH 环境变量中所列出的目录中搜索 %I,并展开到第一个找到结果的驱动器号和路径。
%~ftzaI     将 %I 展开到输出行(如 dir一样)。

在上述范例中,可以用其它有效值替换 %I 和 PATH。有效的 for 变量名终止 %~ syntax。使用大写变量名(例如 %I),可以使代码更具可读性,并且避免与不区分大小写的修改程序混淆。
* 解析字符串
通过将 Filenameset 包括在圆括号内,并且外面再带上单引号(即,'filenameset'),可以使用 for /F 对直接字符串解析逻辑。将 Filenameset 视为从某个文件输入的单行,然后接受解析。
* 解析输出
通过将圆括号之间的 filenameset 变为后面带有引号的字符串,可以利用 for /F 命令解析命令输出。将它作为命令行,此命令被传递给子 cmd.exe,并将输出捕获到内存并进行解析,就象它是一个文件一样。

范例
要在批处理文件中使用 for,请使用以下语法:
for %%variable in (set) do command [CommandLineOptions]

要通过使用可替换变量 %f 显示当前目录中扩展名为 .doc 或 .txt 的所有文件的内容,请键入:
for %f in (*.doc *.txt) do type %f

在前述范例中,当前目录中扩展名为 .doc 或 .txt 的每个文件都被替代为变量 %f ,直到每个文件的内容都显示为止。要在批处理文件中使用该命令,只需使用 %%f 替换 %f 的每个事件。否则忽略此变量,并显示一条错误消息。

要解析文件,同时忽略注释行,请键入:
for /F "eol=; tokens=2,3* delims=," %i in (myfile.txt) do @echo %i %j %k

这个命令解析 myfile.txt 文件的每一行,忽略以分号开头的行,将第二和第三个令牌从各行传递到 FOR 正文(令牌通过逗号或空格分隔)中。FOR 语句的正文引用 %i 以获得第二个令牌,引用 %j 以获得第三个令牌,引用 %k 以获得其余全部令牌。如果您提供的文件名包含空格,请使用引号将文本引起来(例如,"File Name")。要使用引号,必须使用 usebackq。否则,就将引号解释为定义要解析的文字字符串。

%i 在 FOR 语句中明确声明,并且 %j 和 %k 使用 tokens= 隐含声明。只要它不会引起尝试声明高于字母“z”或“Z”的某个变量,则使用 tokens= 可以指定最多 26 个令牌。

要通过将 filenameset 放在括号之间来解析命令输出,请键入:
for /F "usebackq delims==" %i IN (`set`) DO @echo %i

这个范例列举当前环境中的环境变量名。

Goto
在批处理程序中,将 Windows XP 导入到由标签标识的行。找到标签后,程序将处理从下一行开始的命令。

语法
goto label

参数
label
指定所要转向的批处理程序中的行。
/?
在命令提示符显示帮助。

注释
* 使用命令扩展
如果启用了命令扩展(即默认状态),并且使用带有目标标签为 :EOF 的 goto 命令,则可以在不定义标签的情况下将控制传送到当前批处理脚本文件的末端,然后退出批处理脚本文件。使用 goto 和 :EOF 标签时,必须在标签前插入冒号。例如:
goto :EOF

有关使该功能有用的 call 命令的信息,请参阅中的 cmd。
* 使用有效的 label 值
可以在 label 参数中使用空格,但不得包括其他分隔符(例如分号或等号)。goto 命令只使用标签的前八个字符。例如,下面的标签是等效的,且都将解析为 :hithere0:
:hithere0
:hithere01
:hithere02
* 将 label 参数与批处理程序中的标签进行匹配
所指定的 label 值必须与批处理程序中的标签匹配。批处理程序中的标签必须以冒号 (:) 开始。Windows XP 可以识别以冒号 (:) 开头作为标签的批处理程序行并且不会将它作为命令处理。如果某行以冒号开始,则该行的任何命令都将被忽略。如果批处理程序没有包含指定的标签,则批处理程序将停止并显示以下消息:
Label not found
* 对条件操作使用 goto
可以将 goto命令 与其他命令一起使用,从而执行条件操作。有关使用 goto命令 执行条件操作的详细信息,请参阅“”中的 if。

范例
以下批处理程序在驱动器 A 将一张磁盘格式化为系统盘。如果操作成功,则 goto 命令会将 Windows XP 导向 :end 标签:
echo off
format a:/s
if not errorlevel 1 goto end
echo An error occurred during formatting.
:end
echo End of batch program.

If
在批处理程序中执行条件处理。

语法
if [not] errorlevel number command [else expression]
if [not] string1==string2 command [else expression]
if [not] exist filename command [else expression]

如果启用了命令扩展,请使用以下语法:
if [/i] string1 compareop string2 command [else expression]
if cmdextversion number command [else expression]
if defined variable command [else expression]

参数
not
指定只有当条件为假时才执行该命令。
errorlevel number
只有当由 cmd.exe 运行的前一个程序返回大于或等于 number 的退出代码时,才能指定真条件。
command
指定只有满足前面的条件时才应执行的命令。
string1==string2
只有当 string1 和 string2 相同时才能指定真条件。这些值可以是文字字符串或批处理变量(例如,%1)。对于文字字符串,不需要使用问号。
exist filename
如果 filename 存在,则指定真条件。
CompareOp
指定 3 个字母的比较运算符。下表列出了 compareop 的有效值。
运算符     说明
EQU     等于
NEQ     不等于
LSS     少于
LEQ     少于或等于
GTR     大于
GEQ     大于或等于
/i
强制字符串比较忽略大小写。可以在 if 的 string1==string2 形式上使用/i。这些比较是通用的,如果 string1 和 string2 都由所有的数字组成,那么字符串将被转换为数字并且将执行数字比较。
cmdextversion number
只有当与 cmd.exe 的“命令扩展”功能相关的内部版本号等于或大于 number 时,才指定真条件。第一个版本是 1。当命令扩展的功能有重大增强时,则在此号码上加 1。当禁用了命令扩展时(默认情况下为启用),cmdextversion 条件不为真。
defined variable
如果定义了 variable,则指定条件为真。
expression
指定将传递给 else 子句中命令的命令行命令和任何参数。
/?
在命令提示符显示帮助。

注释
* 如果 if 命令中指定的条件为真,则系统将执行该条件后的命令。如果条件为假,则 if 子句中的命令将被忽略,同时执行 else 子句中的任何命令(如果指定)。
* 程序停止时,将返回退出码。可以利用 errorlevel 参数将退出码用作条件。
* 使用 defined variable
如果使用 defined variable,可以添加下面三个变量:%errorlevel%、 %cmdcmdline% 和 %cmdextversion%。
%errorlevel% 扩展到 errorlevel 当前值的字符串表达式,如果没有名为 ERRORLEVEL 的环境变量,就可取代它的值。下面的范例说明了如何在运行批处理程序后使用 errorlevel:
goto answer%errorlevel%
:answer0
echo Program had return code 0
:answer1
echo Program had return code 1
goto end
:end
echo done!

也可以使用如下的 CompareOp 比较运算符:
if %errorlevel% LEQ 1 goto okay
%cmdcmdline% 在任何 cmd.exe 处理之前扩展传递到 cmd.exe 的源命令行,如果没有名为 cmdcmdline 的环境变量,就可取代它的值。
%cmdextversion% 扩展到 cmdextversion 当前值的字符串表达式,如果没有名为 cmdEXTVERSION 的环境变量,就可取代它的值。
* 使用 else 子句
else 子句必须出现在与 if 后的命令相同的行中。例如:
IF EXIST filename. (
del filename.
) ELSE (
echo filename.missing.
)

下面的代码不起作用,因为必须通过重起一行中止 del 命令:
IF EXIST filename. del filename.ELSE echo filename.missing

以下命令不起作用,因为 else 命令必须在与 if 命令的末尾相同的行上:
IF EXIST filename. del filename.
ELSE echo filename.missing

如果要完全在单行上格式化它,可以使用如下形式的原始声明:
IF EXIST filename.(del filename)ELSE echo filename.missing

范例
如果没有找到文件 Product.dat,将会显示如下消息:
if not exist product.dat echo Can't find data file
如果格式化驱动器 A 中的磁盘期间出现错误,则下面范例将会显示错误消息:
:begin
@echo off
format a:/s
if not errorlevel 1 goto end
echo An error occurred during formatting.
:end
echo End of batch program.

如果没有出现错误,将跳过错误消息。
if 命令不能用于直接测试目录,但空 (NUL) 设备确实存在于每个目录中。因此,可以通过测试零设备确定目录是否存在。以下范例可测试目录的存在:

if exist c:mydir\nul goto process

Pause
暂停批处理程序的处理并显示消息,提示用户按任意键继续。

语法
pause

参数
/?
在命令提示符显示帮助。

注释
* 运行 prompt 命令时,将显示下面的消息:
Press any key to continue . . . . .
* 如果按 CTRL+C 停止批处理程序,则将显示下面的消息:
Terminate batch job (Y/N)?
按“Y”(代表“是”)响应这一消息,批处理程序将结束,控制返回到操作系统。因此,可以在不需要处理的批处理文件分段前插入 pause 命令。pause 暂停批处理程序的处理,您可以按 CTRL+C,然后键入 Y 停止批处理程序。

范例
要创建批处理程序,该批处理程序可提示用户更改某个驱动器中的磁盘,请键入:
@echo off
:begin
copy a:*.*
echo Please put a new disk into drive A
pause
goto begin

在此范例中,驱动器 A 中磁盘上的所有文件均复制到当前的目录中。显示的注释提示您将另一张磁盘放入驱动器 A 时,pause 命令会使程序挂起,以便您更换磁盘,然后按任意键继续处理。这种特殊的批程序在死循环中运行。goto BEGIN 命令将命令解释程序发送到批处理文件的开始标签。要停止该批处理程序,按下 CTRL+C 键然后按 Y 键。

Rem
使您可以在批处理文件或配置文件中加入注释。

语法
rem [comment]

参数
comment
指定要作为注释的任何字符串。
/?
在命令提示符显示帮助。

注释
* 使用 echo 命令显示注释
rem 命令不在屏幕上显示注释。必须在批处理或 Config.nt 文件中使用 echo on 命令才能在屏幕上显示注释。
* 对批处理文件注释的限制
在批处理文件注释中不能使用重定向字符“(”或“)”或管道 (|)。
* 使用 rem 增加垂直间距。
尽管您可以使用没有注释的 rem 为批处理文件增加垂直间距,但也可以使用空行来增加间距。在处理批处理程序时会忽略空行。

范例
以下范例显示为解释和垂直间距使用注释的批处理文件:
@echo off
rem This batch program formats and checks new disks.
rem It is named Checknew.bat.
rem
echo Insert new disk in drive B.
pause
format b:/v
chkdsk b:

假定要在 Config.nt 文件中的 prompt 命令前包含解释性注释。为此,请将以下行添加到 Config.nt 中:
rem Set prompt to indicate current directory
prompt $p$g

Setlocal
开始批处理文件中环境变量的本地化。本地化将持续到出现匹配的 endlocal 命令或者到达批处理文件结尾为止。

语法
setlocal {enableextension | disableextensions} {enabledelayedexpansion | disabledelayedexpansion}

参数
enableextension
启用命令扩展,直到出现匹配的
endlocal 命令,无论 setlocal 命令之前的设置如何。
disableextensions
禁用命令扩展,直到出现匹配的 endlocal 命令,无论 setlocal 命令之前的设置如何。
enabledelayedexpansion
启用延迟的环境变量扩展,直到出现匹配的 endlocal 命令,无论 setlocal 命令之前的设置如何。
disabledelayedexpansion
禁用延迟的环境变量扩展,直到出现匹配的 endlocal 命令,无论 setlocal 命令之前的设置如何。
/?
在命令提示符显示帮助。

注释
* 使用 setlocal
当您在脚本或批处理文件外使用 setlocal 时,将没有效果。
* 更改环境变量
运行批处理文件时使用 setlocal 更改环境变量。运行 setlocal 后对环境所作的更改在批处理文件本地。cmd.exe 在遇到 endlocal 命令或者到达批处理文件的结尾时将恢复上一次的设置。
* 在批处理程序中可以包含多个 setlocal 或 endlocal 命令(嵌套)。
* 测试批处理文件中的命令扩展
setlocal 命令设置 ERRORLEVEL 变量。如果遇到 {enableextension | disableextensions} 或 {enabledelayedexpansion | disabledelayedexpansion},ERRORLEVEL 变量将设置成 0 (0)。否则,该变量将被设置成 1 (1)。在批处理脚本中使用该命令可以确定扩展是否可用,例如:
verify other 2>nul
setlocal enableextensions
if errorlevel 1 echo Unable to enable extensions

因为当禁用命令扩展时 cmd 不会设置 ERRORLEVEL 变量,所以当通过无效参数使用 setlocal 命令时 verify 命令将 ERRORLEVEL 变量初始化为非零值。另外,如果通过 {enableextension | disableextensions} 或 {enabledelayedexpansion | disabledelayedexpansion} 参数使用 setlocal 命令,而且没有将 ERRORLEVEL 变量设置成 1 (1) 时,则命令扩展将不可用。
有关启用或禁用命令扩展的详细信息,请参阅“”中的 cmd。

范例
可以在批处理文件中本地化环境变量,如下所示:
rem *******Begin Comment**************
rem This program starts the superapp batch program on the network,
rem directs the output to a file, and displays the file
rem in Notepad.
rem *******End Comment**************
@echo off
setlocal
path=g:\programs\superapp;%path%
call superapp>c:\superapp.out
endlocal
start notepad c:\superapp.out

Shift
更改批处理文件中批处理参数的位置。

语法
shift

参数


注释
* 将 shift 命令行选项与命令扩展一起使用

启用命令扩展(默认设置)后,shift 命令支持 /n 命令行选项,该选项通知命令在第 n 个参数处开始更改,n 可以是 0 到 8 的任何一个值。例如,

SHIFT /2

可以将 %3 改为 %2,将 %4 改为 %3 等等,而 %0 和 %1 保持不变。
* shift 命令的工作原理
shift 命令通过将每个参数复制到前一个参数中,更改批处理参数 %0 到 %9 的值。也就是说,将 %1 的值复制到 %0,%2 的值复制到 %1,依次类推。该命令在撰写对任何数目的参数执行相同操作的批处理文件时非常有用。
* 使用 10 个以上的批处理参数
也可以使用 shift 命令创建可以接受 10 个以上批处理参数的批处理文件。如果在命令行上指定了 10 个以上的参数,第十个 (%9) 参数之后的参数将更改为 %9,一次更改一个。
* 将 %* 与 shift 一起使用
Shift 对 %* 批处理参数没有影响。
* 恢复参数
没有反向的 shift 命令。执行了 shift 命令后,不能恢复更改前存在的第一个批处理参数 (%0)。

范例
以下批处理文件 Mycopy.bat 显示了如何使用包含任意数目批处理参数的 shift 命令。该批处理文件将一列文件复制到特定的目录。批处理参数由目录和文件名参数表示。
@echo off
rem MYCOPY.BAT copies any number of files
rem to a directory.
rem The command uses the following syntax:
rem mycopy dir file1 file2 ...
set todir=%1
:getfile
shift
if "%1"=="" goto end
copy %1 %todir%
goto getfile
:end
set todir=
echo All done