Windows 批处理脚本
本书描述并展示了如何使用 Microsoft 提供的命令解释器 cmd.exe 及其关联命令,以及如何为解释器编写 Windows 批处理脚本。cmd.exe 是所有基于 Windows NT 的操作系统上的默认解释器,包括 Windows XP、Windows 7 和 Windows 10。
本书讨论适用于基于 Windows NT 环境的现代 Windows 版本的 32 位 Windows 命令。它不讨论特定于 DOS 环境和基于 DOS 的操作系统(如 Windows 95、Windows 98 和 Windows Me)的命令,其 Microsoft 提供的命令解释器实际上是 DOS 程序,而不是 Win32 程序。
您可以使用 VER 命令找出您正在运行的 Windows 版本。
本书首先描述如何使用 Windows NT 命令解释器,它如何接收、解析和处理用户的命令。然后描述可用的各种命令。
要获取 Windows 命令及其简要摘要的完整列表,请在任何 Windows 计算机上打开命令提示符,然后键入help。要了解特定命令的信息,请键入命令名称后跟“/?”。
本书的主题也称为“批处理编程”,即使“批处理”不仅指 MS DOS 和 Windows 命令解释器的批处理文件。其他主题术语包括“批处理文件编程”、“批处理文件脚本”、“Windows 批处理命令”、“Windows 批处理文件”、“Windows 命令行”、“Windows 命令提示符”和“Windows shell 脚本”。
对于 Windows 脚本,cmd.exe 是一种传统技术;现代等效项是 PowerShell,它基于 .NET,其管道流是对象,而不是字符(字节)流。PowerShell 的功能远远超过 cmd.exe;PowerShell 具有完整编程语言的功能,包括变量的类型化内容、浮点运算、大整数、通过 .NET 类进行 GUI 编程等。尽管如此,cmd.exe 对于简单的脚本和命令行交互任务仍然有用,通常提供更短的语法和更快的启动时间,以及使用其他操作系统熟悉的字符流管道。cmd.exe 可以通过其他操作系统中已知的命令进行增强;请参阅 #Unix 命令。另一种用于 Windows 脚本的替代方案是流行的 Python 及其 pywin32 和 wmi 库;但是,这需要安装。
将命令行解析为一系列命令的过程很复杂。主要有四个组成部分
- 变量替换:扫描命令行以查找变量规范,并用这些变量的内容替换找到的任何变量。
- 引用:可以引用特殊字符,以删除其特殊含义。
- 语法:根据语法将命令行开发成一系列命令。
- 重定向:在执行序列中的单个命令之前,应用重定向规范并将其从命令行中删除。
命令行可以包含变量规范。这些规范由一个 % 字符、一个名称以及一个第二个 % 字符组成,除非名称是 0 到 9 之间的数字或星号 *。
变量规范按如下方式替换为值
- %varname%,例如 %PATH% 或 %USERNAME% ,将替换为命名环境变量的值。例如,%PATH% 将替换为 PATH 环境变量的值。变量名称匹配不区分大小写:%PATH% 和 %path% 效果相同。
- %n,其中 0 <= n <= 9,例如 %0 或 %9,将替换为调用批处理文件时传递给它的第 n 个参数的值,受 SHIFT 命令随后进行的任何修改的影响。例如:%2 将替换为第二个批处理文件参数的值。在交互式使用(批处理文件之外)中,此情况不会进行替换。
- %* 将替换为所有命令行参数的值,除了 %0 之外,即使是索引 9 之后的参数。 SHIFT 命令对 %* 的结果没有影响。另请参阅 命令行参数。在交互式使用(批处理文件之外)中,此情况不会进行替换。
某些变量名称无法使用 SET 命令查看。相反,它们可以通过 % 符号进行读取。要了解这些变量,请键入“help set”。
特殊变量名称及其扩展内容
名称 | 使用的替换值 |
---|---|
%CD% | 当前目录,如果它不是当前驱动器的根目录,则不以斜杠字符结尾。另请参阅 #CD。 |
%TIME% | 系统时间,格式为 HH:MM:SS.mm,除非区域设置另有规定。另请参阅 #TIME。 |
%DATE% | 系统日期,格式特定于本地化。另请参阅 #DATE。 |
%RANDOM% | 生成的伪随机数,介于 0 和 32767 之间。另请参阅 #计算。 |
%ERRORLEVEL% | 最后一个执行的命令或最后一个调用的批处理脚本返回的错误级别。另请参阅 #错误级别。 |
%CMDEXTVERSION% | cmd.exe 当前使用的命令处理器扩展的版本号。 |
%CMDCMDLINE% | 启动当前 cmd.exe 时使用的命令行的内容。 |
链接
您可以防止控制命令语法的特殊字符具有其特殊含义,方法如下,但百分号 (%) 除外
- 您可以用引号括住包含特殊字符的字符串。
- 您可以在特殊字符之前立即放置脱字符 (^)(转义字符)。在管道 (|) 后面的命令中,您需要使用三个脱字符 (^^^) 才能使其工作。
需要引用或转义的特殊字符通常是 <、>、|、& 和 ^。在某些情况下,! 和 \ 可能需要转义。换行符也可以使用脱字符转义。
当您使用引号括住字符串时,它们会成为传递给调用的命令的参数的一部分。相反,当您使用脱字符作为转义字符时,脱字符不会成为传递的参数的一部分。
百分号 (%) 是一种特殊情况。在命令行中,它不需要引用或转义,除非使用两个百分号来指示变量,例如 %OS%。但在批处理文件中,您必须使用双百分号 (%%) 以生成单个百分号 (%)。将百分号括在引号中或在其前面加上脱字符不起作用。
示例
- echo "Johnson & son"
- 回显整个字符串,而不是在 & 字符处拆分命令行。引号也会回显
- echo Johnson ^& son
- 如上所示,但在特殊字符 & 之前使用脱字符。没有回显引号。
- echo Johnson & son
- 不使用转义字符,因此,“son”被解释为单独的命令,通常会导致找不到命令 son 的错误消息。
- echo A ^^ B
- 回显 A ^ B。脱字符也需要转义,否则它会被解释为转义空格。
- echo > NUL | echo A ^^^^ B
- 回显 A ^ B。在管道之后,用于转义的脱字符需要加倍才能生效;第四个脱字符是正在转义的脱字符。
- if 1 equ 1 ^
echo Equal &^
echo Indeed, equal- 回显这两个字符串。行尾的脱字符转义了换行符,导致三行被视为一行。第一个脱字符之前的空格是必要的,否则 1 会与后面的 echo 连接起来,产生 1echo。
- attrib File^ 1.txt
- 不显示名为“File 1.txt”的文件的属性,因为空格的转义不起作用。使用引号,如 attrib "File 1.txt",可以正常工作。
- echo The ratio was 47%.
- 如果从批处理文件中运行,则忽略百分号。
- echo The ratio was 47%%.
- 如果从批处理文件中运行,则百分号输出一次。
- set /a modulo=14%%3
- 如果从批处理文件中运行,则将 modulo 变量设置为 2,即 14 除以 3 的余数。单个 % 不起作用。
- for %%i in (1,2,3) do echo %%i
- 如果从批处理文件中运行,则输出 1、2 和 3。
- echo %temp%
- 即使从批处理文件中运行,也会输出 temp 变量的内容。在批处理文件中使用百分号访问环境变量和传递的参数不需要转义。
- echo ^%temp^%
- 从命令行运行时,输出 %temp% 本身。
- echo %%temp%%
- 从批处理文件中运行时,输出 %temp% 本身。
- echo //comment line | findstr \//
- 命令 FINDSTR 使用反斜杠 (\) 进行转义。与脱字符不同,这是命令内部的,命令外壳不知道。
链接
命令行根据语法展开为一系列命令。在该语法中,简单命令可以组合成管道,而管道又可以组合成复合命令,最后可以转换为带括号的命令。
简单命令只是一个命令名称、一个命令尾部和一些重定向规范。简单命令的一个示例是dir *.txt > somefile.
管道是由“管道”元字符“|”(也称为“竖线”)连接在一起的几个简单命令。每个竖线之前的简单命令的标准输出通过管道连接到其后的简单命令的标准输入。命令解释器并行运行管道中的所有简单命令。管道(包含两个简单命令)的一个示例是dir *.txt | more.
复合命令是一组由连接词分隔的管道。管道按顺序执行,一个接一个,连接词控制命令解释器是否执行下一个管道。复合命令(包含两个管道,管道本身只是简单命令)的一个示例是move file.txt file.bak && dir > file.txt.
连接词
- & - 无条件连接词。当前管道执行完成后,始终执行下一个管道。
- && - 正条件连接词。如果当前管道以零退出状态完成执行,则执行下一个管道。
- || - 负条件连接词。如果当前管道以非零退出状态完成执行,则执行下一个管道。
带括号的命令是用括号括起来的复合命令(即(和))。从语法的角度来看,这将复合命令转换为简单命令,其整体输出可以重定向。
例如:命令行( pushd temp & dir & popd ) > somefile导致整个复合命令的标准输出( pushd temp & dir & popd )重定向到somefile。
链接
在执行序列中的单个命令之前应用重定向规范,并将其从命令行中删除。重定向规范控制简单命令的标准输入、标准输出和标准错误文件句柄指向的位置。它们会覆盖可能由管道导致的对这些文件句柄的任何影响。(请参阅前面关于命令语法的部分。)重定向符号 > 和 >> 可以以 1(表示标准输出,与无前缀相同)或 2(表示标准错误)为前缀。
重定向规范为
- < filename
- 将标准输入重定向到从命名文件读取。
- > filename
- 将标准输出重定向到指定的命名文件,覆盖其先前的内容。
- > filename
- 将标准输出重定向到指定的命名文件,追加到其先前内容的末尾。
- >>h
- 重定向到句柄h,其中句柄可以是 0 - 标准输入,1 - 标准输出,2 - 标准错误,以及更多。
- <&h
- 从句柄h重定向。
示例
- dir *.txt >listing.log
- 将dir命令的输出重定向到listing.log文件。
- dir *.txt > listing.log
- 如上所述;文件名之前的空格没有区别。但是,如果在命令窗口中输入此命令,在输入“> l”后使用Tab键进行自动完成实际上有效,而使用“>listing.log”则无效。
- dir *.txt 2>NUL
- 将dir命令的错误重定向到无处。
- dir *.txt >>listing.log
- 将dir命令的输出重定向到listing.log文件,并追加到文件末尾。因此,在执行重定向命令之前文件的内容不会丢失。
- dir *.txt >listing.log 2>&1
- 将dir命令的输出以及错误消息重定向到listing.log文件。
- dir *.txt >listing.log 2>listing-errors.log
- 将dir命令的输出重定向到listing.log文件,并将错误消息重定向到listing-errors.log文件。
- >myfile.txt echo Hello
- 重定向可以在命令之前。
- echo Hello & echo World >myfile.txt
- 只有第二个echo被重定向。
- (echo Hello & echo World) >myfile.txt
- 两个echo的输出都被重定向。
- type con >myfile.txt
- 将控制台输入(con)重定向到文件。因此,允许用户输入多行,并通过用户按下Ctrl + Z来终止。另请参见#用户输入。
- (for %i in (1,2,3) do @echo %i) > myfile.txt
- 将循环的整个输出重定向到文件。
- for %i in (1,2,3) do @echo %i > myfile.txt
- 每次进入循环体时都重新开始重定向,丢失了除最新循环迭代之外的所有输出。
链接
(...)
命令解释器在每次执行一行或括号分组后重新加载批处理的内容。
如果启动以下批处理并在启动后不久将批处理中的“echo A”更改为“echo B”,则输出将为B。
@echo off ping -n 6 127.0.0.1 >nul & REM wait echo A
单行上的内容很重要;在运行后更改以下批处理中的“echo A”不会有任何影响
@echo off ping -n 6 127.0.0.1 >nul & echo A
启动后更改对用(和)括起来的命令也没有任何影响。因此,在启动以下批处理后更改“echo A”不会有任何影响
@echo off for /L %%i in (1,1,10) do ( ping -n 2 127.0.0.1 >nul & REM wait echo A )
其他任何包含,包括此包含,也是如此
@echo off ( ping -n 6 127.0.0.1 >nul & REM wait echo A )
命令解释器进程的环境变量会被其执行的任何(外部)命令的进程继承。一些环境变量由命令解释器本身使用。更改它们会改变其操作。
要取消设置变量,请将其设置为空字符串,例如“set myvar=”。
命令解释器从创建它的进程继承其初始的环境变量集。例如,对于从桌面快捷方式调用的命令解释器,这将是Windows资源管理器。
命令解释器通常具有文本用户界面,而不是图形用户界面,因此无法识别通知应用程序注册表中环境变量模板已更改的Windows消息。更改控制面板中的环境变量将导致Windows资源管理器从注册表中的模板更新其自己的环境变量,从而更改任何随后调用的命令解释器将继承的环境变量。但是,它不会导致正在运行的命令解释器从注册表中的模板更新其环境变量。
另请参见#变量替换。
链接
COMSPEC环境变量包含命令解释器程序文件的完整路径名。这只是从父进程继承的,因此间接地派生自注册表中环境变量模板中COMSPEC的设置。
PATH环境变量的值包含一个目录名称列表,这些名称由分号字符分隔。这是按顺序搜索的目录列表,用于查找要执行的外部命令的程序文件。
PATHEXT环境变量的值是文件名扩展名的列表,由分号(“;”)分隔。这是按顺序应用的文件名扩展名列表,用于查找要执行的外部命令的程序文件。
"echo %PATHEXT%"打印的PATHEXT示例内容
- .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
通过将“.PL”添加到变量中,可以确保即使在不带“.pl”扩展名的情况下键入,Perl程序也能从命令行运行。因此,无需键入“mydiff.pl a.txt b.txt”,只需键入“mydiff a.txt b.txt”即可。
在Windows Vista及更高版本中将“.PL”添加到变量
- setx PATHEXT %PATHEXT%;.PL
- 如果使用Windows XP中提供的“set”,则效果是临时的,并且只影响当前控制台或进程。
链接
PROMPT环境变量控制命令解释器显示提示时发出的文本。命令解释器在交互模式下提示输入新命令行时或在批处理文件模式下回显批处理文件行时显示提示。
PROMPT环境变量值中的各种特殊字符序列在显示提示时会导致各种特殊效果,如下表所示
字符 | 扩展结果 |
---|---|
$$ | $字符本身 |
$A | &符号,也称为与号。一个便利,因为它很难在使用SET命令时将字面量&放在PROMPT环境变量的值中。 |
$B | 竖线'|'(管道符号) |
$C | 左括号'(' |
$D | 当前日期 |
$E | ESC(ASCII码27) |
$F | 右括号')' |
$G | 大于号'>' |
$H | 退格键(删除前一个字符) |
$L | 小于号'<' |
$M | 如果当前驱动器是网络驱动器,则链接到当前驱动器的远程名称;否则为空字符串。 |
$N | 当前驱动器盘符 |
$P | 当前驱动器盘符和完整路径 |
$Q | '='(等号) |
$S | ' '(空格字符) |
$T | 当前系统时间 |
$V | Windows版本号 |
$_ | <CR>(回车符,也称为“enter”) |
$+ | 与pushd目录堆栈中的项目数量一样多的加号(+) |
链接
大多数Windows命令都提供开关,也称为选项,以指导其行为。
观察结果
- 开关通常由单个字母组成;一些开关由多个字母的序列组成。
- 开关前面是斜杠(/),而不是像某些其他操作系统那样使用减号(-)。
- 开关不区分大小写,而不是像某些其他操作系统那样区分大小写。
- 如果将来自其他操作系统的命令移植到Windows(例如grep),它通常会保留原始操作系统的选项约定,包括使用减号和区分大小写。
示例
- dir /?
- 输出帮助。许多命令都提供此选项。
- dir /b /s
- 递归列出当前文件夹中的所有文件和文件夹。使用两个开关:b和s。
- dir /bs
- 无效;开关不能累积在一个斜杠后面。
- findstr /ric:"id: *[0-9]*" File.txt
- 与许多其他命令不同,findstr允许在一个斜杠后面累积开关。实际上,r、i和c是单个字母开关。
- dir/b/s
- 有效。在dir中,命令与第一个开关之间或开关之间的空格不影响结果;因此,与dir /b /s相同。
- tree/f/a
- 无效,与tree /f /a不同。在tree中,空格分隔是必须的。find/i/v也不起作用。
- dir /od
- 开关字母o由一个字母进一步修改,指定按日期排序。字母d本身不是开关。类似的情况包括dir /ad和more /t4。
- dir /B /S
- 开关不区分大小写,与某些其他操作系统不同。
- sort /r file.txt
- 以相反的顺序对文件进行排序。
- sort /reverse file.txt
- Sort允许开关字符串的长度超过单个字母。
- sort /reve file.txt
- Sort允许指定的开关字符串是开关完整长名称的子字符串。因此,与上面相同。
- sort /reva file.txt
- 无效,因为“reva”不是“reverse”的子字符串。
- taskkill /im AcroRd32.exe
- Taskkill 命令需要使用多字母开关名称,例如 /im;缩写为 /i 不起作用。
- java -version
- Java 诞生于另一个操作系统系列的环境中,其开关(也称为选项)使用减号约定。
- grep --help
- 如果安装了 GNU grep,则需要在多字母开关前加上两个连字符。
命令通常在执行结束时设置错误级别。在 Windows NT 及更高版本中,它是一个 32 位有符号整数;在 MS DOS 中,它曾经是一个 0 到 255 的整数。关键词:返回码、退出码、退出状态。
错误级别的常规含义
- 0 - 成功
- 非 0 - 失败
- 设置的错误级别通常为正数。
- 如果命令不区分各种类型的失败,则失败时的错误级别通常为 1。
错误级别的用途
示例
- dir >NUL && echo Success
- 只有当错误级别为零时,才会执行 && 后面的部分。
- color 00 || echo Failure
- 只有当错误级别非零时,无论正负,才会执行 || 后面的部分。
- color 00 || (
echo Failure
)- 多行括号也能正常工作。
- echo %ERRORLEVEL%
- 输出错误级别而不改变它。
- if %errorlevel% equ 0 echo 错误级别为零,表示成功。
- if %errorlevel% neq 0 echo 错误级别非零,表示失败。
- if errorlevel 1 echo 错误级别 >= 1,表示通过正错误级别失败。
- 不涵盖通过负错误级别失败的情况。请注意“>=”部分:这与 if %errorlevel% equ 1 不同。
- exit /b 1
- 返回一个批处理文件,并将错误级别设置为 1。
- cmd /c "exit /b 10"
- 在批处理文件的中间或命令行上,将错误级别设置为 10。
- (cmd /c "exit /b 0" && Echo Success) & (cmd /c "exit /b -1" || Echo Failure)
- 如上所示,错误级别确实受到影响。
- (cmd /c "exit /b 0" & cmd /c "exit /b 1") || Echo Failure
- 由 & 创建的链的错误级别是链中最后一个命令的错误级别。
- cmd /c "exit /b -1" & if not errorlevel 1 echo 可能是成功
- “if not errorlevel 1” 测试,看起来像是测试成功,但在负数上也会通过:它测试“错误级别不 >= 1”,也就是“错误级别 <= 0”。
- set myerrorlevel=%errorlevel%
- 记住错误级别以供以后使用。
- set errorlevel=0
- 应避免:覆盖内置的 errorlevel 变量。确保后续通过 %ERRORLEVEL% 访问时返回 0 而不是实际的错误级别。
- cmd /c "exit /b 0"
if 1 equ 1 ( cmd /c "exit /b 1" & echo %errorlevel% )- 输出 0,因为 %errorlevel% 在 cmd /c "exit /b 1" 执行之前就被扩展了。
链接
获取非空变量的子字符串
set a=abcdefgh
echo %a:~0,1% & rem from index 0, length 1; result: a
echo %a:~1,1% & rem from index 1, length 1; result: b
echo %a:~0,2% & rem from index 0, length 2; result: ab
echo %a:~1,2% & rem from index 1, length 2; result: bc
echo %a:~1% & rem from index 1 to the end; result: bcdefgh
echo %a:~-1% & rem from index -1 (last char) to the end; result: h
echo %a:~-2% & rem from index -2 (next-to-last) to the end; result: gh
echo %a:~0,-2% & rem from index 0 to index -2, excl.; result: abcdef
echo %a:~0,-1% & rem from index 0 to index -1, excl.; result: abcdefg
echo %a:~1,-1% & rem from index 1 to index -1, excl.; result: bcdefg
测试子字符串是否包含
- if not "%a:bc=%"=="%a%" echo yes
- 如果变量 a 包含“bc”作为子字符串,则回显“yes”。
- 此测试是一个技巧,使用了下面讨论的字符串替换。
- 如果变量包含引号,则此测试不起作用。
测试“以…开头”
if %a:~0,1%==a echo yes & rem If variable a starts with "a", echo "yes".
if %a:~0,2%==ab echo yes & rem If variable a starts with "ab", echo "yes".
字符串替换
set a=abcd & echo %a:c=% & rem replace c with nothing; result: abd
set a=abcd & echo %a:c=e% & rem replace c with e; result: abed;
set a=abcd & echo %a:*c=% & rem replace all up to c with nothing; result: d
rem Above, the asterisk (*) only works at the beginning of the sought pattern.
另请参见 SET 命令的帮助:set /?。
按“ ”、“,”和“;”中的任意一个分割字符串:[“空格”、“逗号”和“分号”]:
set myvar=a b,c;d
for %%a in (%myvar%) do echo %%a
按分号分割字符串,假设字符串不包含引号
@echo off
set myvar=a b;c;d
set strippedvar=%myvar%
:repeat
for /f "delims=;" %%a in ("%strippedvar%") do echo %%a
set prestrippedvar=%strippedvar%
set strippedvar=%strippedvar:*;=%
if not "%prestrippedvar:;=%"=="%prestrippedvar%" goto :repeat
限制
- 上述字符串处理不适用于参数变量(%1、%2、…)。
链接
传递给批处理脚本的命令行参数(也称为命令行参数)可以通过 %1、%2、…、%9 访问。参数可以超过九个;要访问它们,请参阅下面如何循环遍历所有参数。
语法 %0 不引用命令行参数,而是引用批处理文件的名称。
测试是否提供了第一个命令行参数
if not -%1-==-- echo Argument one provided
if -%1-==-- echo Argument one not provided & exit /b
使用 SHIFT 循环遍历所有命令行参数(对于每个命令行参数,…)
:argactionstart
if -%1-==-- goto argactionend
echo %1 & REM Or do any other thing with the argument
shift
goto argactionstart
:argactionend
使用 SHIFT 循环遍历所有命令行参数,而不修改 %1、%2 等。
call :argactionstart %*
echo Arg one: %1 & REM %1, %2, etc. are unmodified in this location
exit /b
:argactionstart
if -%1-==-- goto argactionend
echo %1 & REM Or do any other thing with the argument
shift
goto argactionstart
:argactionend
exit /b
将命令行参数传递到环境变量
setlocal EnableDelayedExpansion
REM Prevent affecting possible callers of the batch
REM Without delayed expansion, !arg%argno%! used below won't work.
set argcount=0
:argactionstart
if -%1-==-- goto argactionend
set /a argcount+=1
set arg%argcount%=%1
shift
goto argactionstart
:argactionend
set argno=0
:loopstart
set /a argno+=1
if %argno% gtr %argcount% goto loopend
echo !arg%argno%! & REM Or do any other thing with the argument
goto loopstart
:loopend
循环遍历所有命令行参数,尽管不是稳健的
for %%i in (%*) do (
echo %%i
)
这看起来很优雅,但并不稳健,会错误处理包含通配符(*、?)的参数。特别是,上述 for 命令会将包含通配符(*、?)的参数替换为与之匹配的文件名,或者如果找不到匹配文件则将其删除。尽管如此,只要传递的参数不包含通配符,上述循环就能按预期工作。
以非稳健的方式查找命令行参数的数量
set argcount=0
for %%i in (%*) do set /a argcount+=1
同样,这在处理包含通配符的参数时不起作用。
最大可能的参数数量大于 4000,这在 Windows Vista 机器上经过实证确定。在 Windows XP 和 Windows 7 上,此数字可能会有所不同。
在将参数传递给批处理脚本时,用于参数分隔的字符如下
- 空格
- 逗号
- 分号
- 等号
- 制表符
因此,以下行传递了相同的四个参数
- test.bat a b c d
- test.bat a,b,c,d
- test.bat a, b, c, d
- test.bat a;b;c;d
- test.bat a=b=c=d
- test.bat a b,c;,;=d
是的,即使包含“a b,c;,;=d”的行也传递了四个参数,因为分隔符的序列被视为单个分隔符。
要在参数值中包含空格、逗号或分号,可以将值用引号括起来。但是,引号会成为参数值的一部分。要在脚本中引用参数时删除封闭的引号,可以使用 #百分号波浪线 中描述的 %~<number>。
在将参数传递给调用的命令而不是批处理脚本时,通常需要使用空格将命令与第一个参数分隔开。但是,对于内部命令,如果命令名称后面的第一个字符是几个符号之一,包括 .\/ 等,则不需要此分隔符。
- echo.
- 输出一个换行符。
- tree.
- 失败:“tree.” 未找到。tree 是一个外部命令。
- dir..
- 列出父目录的内容。
- cd..
- 将当前目录更改为父目录。
- cd\
- 将当前目录更改为根目录。
- start.
- 从当前目录打开 Windows 资源管理器。
- dir/b/s
- 递归列出目录内容,显示完整路径。
链接
许多命令接受文件名通配符——不代表自身并能够匹配一组文件名的字符。
通配符
- *(星号):任意字符序列
- ?(问号):单个字符,但不包括句点(“.”),或者如果它是文件名最大无句点部分末尾的一系列问号的一部分,则可能为零个字符;请参阅示例以了解说明
示例
- dir *.txt
- 匹配 Myfile.txt、Plan.txt 和任何其他扩展名为 .txt 的文件。
- dir *txt
- 不需要包含句点。但是,这也将匹配未按句点约定命名的文件,例如 myfiletxt。
- ren *.cxx *.cpp
- 将所有扩展名为 .cxx 的文件重命名为扩展名为 .cpp 的文件。
- dir a?b.txt
- 匹配文件 aab.txt、abb.txt、a0b.txt 等。
- 不匹配 ab.txt,因为后跟非问号或句点的问号不能匹配零个字符。
- 不匹配 a.b.txt,因为问号不能匹配句点。
- dir ???.txt
- 匹配 .txt、a.txt、aa.txt 和 aaa.txt 等,因为后跟句点的序列中的每个问号都可以匹配零个字符。
- dir a???.b???.txt???
- 匹配 a.b.txt 等。虽然最后一个问号序列后没有句点,但它仍然是文件名最大无句点部分末尾的序列。
- dir ????????.txt & @REM 八个问号
- 匹配与 *.txt 相同的文件,因为每个文件也有一个短文件名,在 .txt 之前最多有 8 个字符。
短文件名的怪癖:通配符匹配同时在长文件名和通常隐藏的 8 个字符 + 句点 + 3 个字符的文件名上执行。这可能导致意外情况。
与某些其他操作系统的 shell 不同,cmd.exe shell 不会自行执行通配符扩展(将包含通配符的模式替换为与该模式匹配的文件名列表)。每个程序都有责任将通配符视为通配符。这使得诸如“ren *.txt *.bat”这样的操作成为可能,因为 ren 命令实际上看到了 * 通配符而不是与通配符匹配的文件列表。因此,“echo *.txt”不会显示当前文件夹中与该模式匹配的文件,而是按字面输出“*.txt”。另一个结果是,您可以编写“findstr a.*txt”而不用担心“a.*txt”部分会被当前文件夹中某些文件的名称替换。此外,递归“findstr /s pattern *.txt”是可能的,而在某些其他操作系统中,“*.txt”部分将被替换为在当前文件夹中找到的文件名,而忽略嵌套文件夹。
接受通配符的命令包括ATTRIB、COPY、DIR、FINDSTR、FOR、REN等。
链接
您可以使用以下方法获取用户输入
当命令行参数包含文件名时,可以使用特殊语法获取有关该文件的各种信息。
以下语法扩展到有关作为 %1 传递的文件的各种信息
语法 | 扩展结果 | 示例 |
---|---|---|
%~1 | %1 无需包含引号 | 未提供 |
%~f1 | 带驱动器盘符的完整路径 | C:\Windows\System32\notepad.exe |
%~d1 | 驱动器盘符 | C |
%~p1 | 不带驱动器盘符的路径,并在末尾带反斜杠 | \Windows\System32\ |
%~n1 | 对于文件,则为不带路径和扩展名的文件名 对于文件夹,则为文件夹名称 |
notepad |
%~x1 | 包含句点的文件名扩展名 | .exe |
%~s1 | 修改 f、n 和 x 以使用短名称 | C:\PROGRA~2\WINDOW~3\ACCESS~1\wordpad.exe |
%~a1 | 文件属性 | --a------ |
%~t1 | 文件的上次修改日期和时间(格式取决于 Windows 的“区域格式”设置) | 02.11.2006 11:45(例如“英语(美国)”格式) |
%~z1 | 文件大小 | 151040 |
%~pn1 | p 和 n 的组合 | \Windows\System32\notepad |
%~dpnx1 | 多个字母的组合 | C:\Windows\System32\notepad.exe |
%~$PATH:1 | 在 PATH 变量中存在的文件夹中找到的第一个匹配项的完整路径,或者在没有匹配项时为空字符串。 | |
%~n0 | 对 %0 应用 %~n 批处理文件的无扩展名名称 |
tildetest |
%~nx0 | 对 %0 应用 %~nx 批处理文件的名称 |
tildetest.bat |
%~d0 | 对 %0 应用 %~d 批处理文件的驱动器盘符 |
C |
%~dp0 | 对 %0 应用 %~dp 批处理文件的文件夹,并在末尾带反斜杠 |
C:\Users\Joe Hoe\ |
相同的语法适用于由FOR命令创建的单字母变量,例如“%%i”。
要从命令行了解此主题,请键入“call /?”或“for /?”。
链接
函数(也称为子程序)可以使用CALL、标签、SETLOCAL和ENDLOCAL进行模拟。
确定算术幂的函数示例
@echo off
call :power 2 4
echo %result%
rem Prints 16, determined as 2 * 2 * 2 * 2
goto :eof
rem __Function power______________________
rem Arguments: %1 and %2
:power
setlocal
set counter=%2
set interim_product=%1
:power_loop
if %counter% gtr 1 (
set /a interim_product=interim_product * %1
set /a counter=counter - 1
goto :power_loop
)
endlocal & set result=%interim_product%
goto :eof
虽然函数末尾的 goto :eof 实际上并不需要,但在存在多个函数的常规情况下必须存在。
结果应存储到的变量可以在调用行中指定,如下所示
@echo off
call :sayhello result=world
echo %result%
exit /b
:sayhello
set %1=Hello %2
REM Set %1 to set the returning value
exit /b
在上面的示例中,exit /b 用于代替 goto :eof 以达到相同的效果。
此外,请记住等号是分隔参数的一种方法。因此,以下项目实现了相同的功能
- call :sayhello result=world
- call :sayhello result world
- call :sayhello result,world
- call :sayhello result;world
(请参阅命令行参数作为提醒)
链接
批处理脚本可以使用SET /a 命令执行简单的 32 位有符号整数算术运算和按位运算。支持的最大整数为 2147483647 = 2 ^ 31 - 1。支持的最小整数为 -2147483648 = - (2 ^ 31),可以使用 set /a num=-2147483647-1 的技巧分配。语法让人联想到 C 语言。
算术运算符包括 *、/、 %(模)、+、-。在批处理中,模必须输入为“%%”。没有幂运算符。
按位运算符将数字解释为 32 个二进制数字的序列。这些是 ~(补码)、&(与)、|(或)、^(异或)、<<(左移)、>>(算术/带符号右移)。没有逻辑/无符号右移和位旋转运算符。
否定逻辑运算符为 !:它将零转换为一,将非零转换为零。
组合运算符为,:它允许在一个 set 命令中进行更多计算。
组合赋值运算符以“+=”为模型,在“a+=b”中表示“a=a+b”。因此,“a-=b”表示“a=a-b”。对于 *=、/=、 %=、&=、^=、|=、<<= 和 >>= 也是如此。
支持运算符的优先级顺序如下
- ( )
- * / % + -
- << >>
- &
- ^
- |
- = *= /= %= += -= &= ^= |= <<= >>=
- ,
文字可以输入为十进制(1234)、十六进制(0xffff,前导 0x)和八进制(0777,前导 0)。
负整数的内部位表示为二进制补码。这提供了对负整数的按位运算、十六进制文字大于 0x7FFFFFFF 并小于或等于 0xFFFFFFFF 的赋值和算术结果,以及算术运算的溢出和下溢行为。例如,-2147483648 表示为 0x80000000,因此二进制补码运算“set /a num=~(-2147483647-1)”产生 2147483647,等于 0x7FFFFFFF(键入 set /a num=0x7FFFFFFF 进行检查)。再举一个例子,“-2 & 0xF”产生 14,因为 -2 为 0xFFFFFFFE,与 0xF 进行与运算产生 0xE,即 14。虽然最大十进制文字为 2147483647,但最大十六进制文字为 0xFFFFFFFF,它被分配为十进制 -1。类似地,0xFFFFFFFE 被分配为十进制 -2,依此类推,因此,例如 0xFFFFFFFE - 2 产生 -4。大于 0xFFFFFFFF 的十六进制文字转换为 -1,例如 0xFFFFFFFFFFFFFFFF,而大于 2147483647 的十进制文字会产生错误。最小的可表示 32 位有符号整数为 -2147483648;“-2147483648”不能直接分配,因为这被解释为 -1 * 2147483648,而 2147483648 大于最大十进制文字 2147483647;但是,-2147483647-1 可以解决此问题,0x80000000 也可以。“-2147483647-2”下溢到最大的正整数 2147483647;类似地,“-2147483647-3”下溢到 2147483646。在另一个方向上,“2147483647+1”溢出到 -2147483648,这对应于在内部位表示上执行加法,就好像它是无符号的一样;“2147483647+2”溢出到 -2147483647,依此类推。
由于某些运算符对命令解释器具有特殊含义,因此使用它们的表达式需要用引号括起来,例如
- set /a num="255^127"
- set /a "num=255^127"
- 引号的替代放置。
- set /a num=255^^127
- 使用 ^ 而不是引号转义 ^。
示例
- set /a n=(2+3)*5
- 执行简单的计算并将结果存储到环境变量 n 中。在交互式调用(在批处理之外)时,输出计算结果,否则不输出任何内容。
- set /a (2+3)*5
- 在交互式调用(在批处理之外)时,输出计算结果,否则不输出任何内容。不更改任何变量,仅对交互式使用有用。
- set n1=40 & set n2=25
set /a n3=%n1%+%n2%
- 使用标准百分号表示法进行变量扩展。
- set n1=40 & set n2=25
set /a n3=n1+n2
- 避免在变量名称周围使用百分号表示法,因为对于 /a 来说不需要。
- set /a num="255^127"
- 将“^”括在引号中以防止其对命令解释器的特殊含义。
- set /a n1 = (10 + 5)/5
- 在 /a 中,= 周围的空格无关紧要。但是,习惯于它可以让你在没有 /a 的情况下编写“set var = value”,这会设置“var ”的值而不是“var”。
- if 1==1 (set /a n1=(2+4)*5)
- 不起作用:分组括号内的算术括号会导致问题。
- if 1==1 (set /a n1=^(2+4^)*5)
- 使用脱字符 (^) 转义算术括号可以解决问题,将“n1=2+(4*5)”括在引号中也可以解决问题。
- set /a n1=2+3,n2=4*7
- 执行两次计算。
- set /a n1=n2=2
- 与 n1=2,n2=2 效果相同。
- set n1=40 & set n2=25 & set /a n3=n1+n2
- 按预期工作。
- set /a n1=2,n2=3,n3=n1+n2
- 按预期工作。
- set n1=40 & set n2=25 & set /a n3=%n1%+%n2%
- 除非之前设置了 n1 和 n2,否则不起作用。变量规范“%n1%”和“%n2%”在第一个 set 命令执行之前就被展开。去掉百分号符号可以使其工作。
- set /a n1=2,n2=3,n3=%n1%+%n2%
- 除非之前设置了 n1 和 n2,否则不起作用,原因与上一个示例中说明的一致。
- set /a n1=0xffff
- 使用十六进制表示法将 n1 设置为“65535”。
- set /a n1=0777
- 使用八进制表示法将 n1 设置为“511”。
- set /a n1=0xffffffff
- 将 n1 设置为 -1。
- set /a n1="~0"
- 将 n1 设置为 -1,这与负整数的底层二进制补码表示保持一致。因此,非负整数的按位取反 (~) 会产生负整数。
- set /a "n1=-1>>1"
- 由于“>>”运算符是算术右移,保留了带符号 32 位整数的底层二进制表示的最高位,因此输出 -1 作为结果。请注意,-1 在内部表示为 0xFFFFFFFF。逻辑右移(丢弃最高位的)将导致 0x7FFFFFFF,即最大正 32 位整数。
- set /a "n1=(-1>>1) & 0x7FFFFFFF"
- 通过清除 32 位带符号整数的底层二进制表示的最高位来模拟逻辑右移(丢弃最高位的)1 位。
- set /a "n=-1, shiftcount=4, n1=(n>>shiftcount) & (0x7FFFFFFF >> (shiftcount-1))"
- 模拟逻辑右移,适用于 shiftcount > 0 的情况,当右移超过 1 位时,需要清除多个最高位。
- set /a "n1=1<<32"
- 当右操作数为 32 或更高,或为负数时,将产生 0。这与现代 x86 处理器上的左移指令的行为不同,对于 32 位寄存器,该指令会将右操作数屏蔽为 5 位。因此,使用 x86 指令,结果将为 1,因为 32 & 0x1F 为 0。在 C 语言中,结果未定义,实际结果取决于平台。
- set /a n1=%random%
- 一个伪随机数,范围从 0 到 32767 = 2^15-1。
- set /a n1="%random%>>10"
- 一个伪随机数,范围从 0 到 31 = 2^5-1。右移运算符丢弃了 15 位中的 10 位,保留了 5 位。
- set /a n1=%random%%50
- 一个伪随机数,范围从 0 到 49。使用 % 模运算符。在批处理中,需要使用 %% 进行模运算:set /a n1=%random%%%50。由于模运算的这种特殊用法,结果并非完全均匀;如果第二个模运算操作数(上面为 50)等于 2 的幂,例如 256 = 2^8,则结果是均匀的。
- set /a n1="(%random%<<15)+%random%"
- 一个伪随机数,范围从 0 到 1073741823 = 2^30 - 1。将 %random% 单独产生的两个 15 位随机数组合起来,生成一个 30 位随机数。
- set /a n1="((%random%<<15)+%random%)%1000000"
- 如上所述,但再次使用模运算,这次是为了达到 0 到 999999 的范围。
一个打印素数的示例计算
@echo off
setlocal
set n=1
:print_primes_loop
set /a n=n+1
set cand_divisor=1
:print_primes_loop2
set /a cand_divisor=cand_divisor+1
set /a cand_divisor_squared=cand_divisor*cand_divisor
if %cand_divisor_squared% gtr %n% echo Prime %n% & goto :print_primes_loop
set /a modulo=n%%cand_divisor
if %modulo% equ 0 goto :print_primes_loop & REM Not a prime
goto :print_primes_loop2
链接
- 设置在 ss64.com
- 设置在 Microsoft
- ss64.com 上的随机数
- CMD.EXE 解析数字的规则,作者 dbenham,dostips.com
- 按位运算 # 批处理文件,rosettacode.org
可以使用 #DIR、#FOR、#FINDSTR、#FORFILES 和 #WHERE 查找文件。
示例
- dir /b /s *base*.doc*
- 输出当前文件夹及其子文件夹中所有文件名在扩展名之前包含“base”且扩展名以“doc”开头(包括“doc”和“docx”)的文件。这些文件以完整路径输出,每行一个文件。
- dir /b /s *.txt | findstr /i pers.*doc
- 将输出文件及其完整路径的结果与支持有限正则表达式的 findstr 过滤命令结合起来,形成一种通用而强大的文件查找组合,可以通过文件名和目录名查找文件。
- for /r %i in (*) do @if %~zi geq 1000000 echo %~zi %i
- 对于当前文件夹及其子文件夹中大小大于或等于 1,000,000 字节的每个文件,输出文件大小(以字节为单位)和文件的完整路径。有关 %~zi 中的语法,请参阅 #百分号波浪线。
- forfiles /s /d 06/10/2015 /c "cmd /c echo @fdate @path"
- 对于当前文件夹及其子文件夹中 2015 年 6 月 10 日或之后修改的每个文件,输出文件的修改日期和完整文件路径。/d 后面的日期格式特定于区域设置。因此,允许查找最近修改的文件。
- (for /r %i in (*) do @echo %~ti :: %i) | findstr 2015.*:
- 递归搜索当前文件夹,输出最后修改日期在 2015 年的文件。在文件名之前放置修改日期和时间,后跟双冒号。只要使用的 Windows 版本和区域设置以包含四位数年份的格式显示日期,此方法就能正常工作。双冒号用于确保 findstr 命令匹配日期而不是文件名。
- for /r %i in (*) do @echo %~ti | findstr 2015 >NUL && echo %i
- 如上所述,输出 2015 年更改的文件。与上面不同的是,仅输出文件,不输出修改日期。
- findstr /i /s /m cat.*mat *.txt
- 根据文件内容查找文件。在以 .txt 结尾的文件中执行对正则表达式 cat.*mat 的全文搜索,并输出文件名。/m 开关确保仅输出文件名。
- where *.bat
- 输出当前目录和 PATH 中目录中的所有 .bat 文件。
当从标准控制台(在按 Windows + R 后键入 cmd.exe 后出现)使用 Windows 命令行时,可以使用多个键盘快捷键,包括功能键。
- Tab:从当前文件夹中的文件名或文件夹名中完成已键入字符串的相关部分。相关部分通常是最后一个无空格的部分,但使用引号会更改这一点。通常同时考虑文件和文件夹以进行完成,但 cd 命令仅考虑文件夹。
- 向上和向下箭头键:一次输入一个命令历史记录中的命令。
- Escape:擦除当前正在键入的命令行。
- F1:一次输入一个字符,从命令历史记录中输入单个先前输入的命令的字符。每次后续按下 F1 都会输入一个字符。
- F2:要求您键入一个字符,然后输入命令历史记录中先前命令的最短前缀,该前缀不包含键入的字符。因此,如果先前命令是 echo Hello world 并且您键入了 o,则输入 ech。
- F3:输入命令历史记录中的单个先前命令。重复按下不会产生进一步的效果。
- F4:要求您键入一个字符,然后擦除当前键入的字符串中从当前光标位置开始、向右继续并以您输入的字符(不包括该字符)结束的部分。因此,如果您键入 echo Hello world,使用左箭头键将光标置于 H,按 F4 然后按 w,您将得到 echo world。如果您按 F4 然后按 Enter,则会擦除从光标到行尾的文本。
- F5:一次输入一个命令历史记录中的先前命令。
- F6:输入 Control+Z 字符。
- F7:打开一个基于字符的弹出窗口,其中包含命令历史记录,并允许您使用箭头键和 Enter 选择命令。在弹出窗口中按 Enter 后,命令将立即执行。
- F8:给定一个已键入的字符串,一次显示命令历史记录中以该字符串作为前缀的项目。
- F9:允许您输入命令历史记录中命令的编号,然后执行该命令。
- Alt + F7:擦除命令历史记录。
以上也称为命令提示符键盘快捷键。
这些快捷键的可用性似乎不依赖于运行 DOSKEY。
链接
文件和目录路径遵循某些约定。这些约定包括可能使用驱动器号后跟冒号 (:)、使用反斜杠 (\) 作为路径分隔符以及区分相对路径和绝对路径。
正斜杠 (/) 通常可以用作 (\) 的替代,但并非总是如此;它通常用于标记开关(选项)。使用正斜杠可能导致各种模糊的行为,最好避免。
特殊设备名称包括 NUL、CON、PRN、AUX、COM1、...、COM9、LPT1、...、LPT9;这些可以重定向到。
示例
- attrib C:\Windows\System32\notepad.exe
- 如果文件存在,则成功,这应该是正确的。这是一个带有驱动器号的绝对路径。它也称为完全限定路径。
- attrib \Windows\System32\notepad.exe
- 如果当前驱动器为 C: 且文件存在,则成功,这应该是正确的。这是一个没有驱动器号的绝对路径。
- cd /d C:\Windows & attrib System32\notepad.exe
- 如果文件存在,则成功。传递给 attrib 的路径是相对路径。
- cd /d C:\Windows\System32 & attrib C:notepad.exe
- 如果文件存在,则成功。传递给 attrib 的路径是相对路径,尽管包含驱动器号:必须存在带有反斜杠的 C:\notepad.exe 才能使其成为绝对路径。
- cd /d C:\Windows & attrib .\System32\notepad.exe
- 如果文件存在,则成功。单个句点表示当前文件夹。
- attrib .
- 单个句点表示当前文件夹。
- cd /d C:\Windows & attrib .\System32\\\notepad.exe
- 如果文件存在,则成功。反斜杠的堆叠除了第一个反斜杠之外没有其他影响。
- cd /d C:\Windows & attrib .\System32
- 如果文件夹存在则成功。
- cd /d C:\Windows & attrib .\System32\
- 失败。文件夹通常不带最后的反斜杠表示。
- cd C:\Windows\System32\
- 成功,无论如何。
- cd ..
- 双点表示父文件夹。
- attrib C:\Windows\System32\..\..\Windows\System32
- 双点可以用于路径中间,以导航到父文件夹,甚至多次。
- attrib \\myserver\myvolume
- 网络 UNC 路径以双反斜杠开头,没有驱动器号。
- cd \\myserver\myvolume
- 不起作用;以这种直接方式更改到服务器文件夹不起作用。
- pushd \\myserver\folder
- 自动为文件夹创建驱动器并切换到该驱动器。使用#POPD后,驱动器将再次取消分配。
- attrib C:/Windows/System32/notepad.exe
- 在多个版本的 cmd.exe 上成功。使用正斜杠。
链接
- 长文件名、NTFS 和 ss64.com 上的合法文件名字符
- Microsoft 上的文件、路径和命名空间命名
- W:路径(计算)#MS-DOS/Microsoft Windows 样式,wikipedia.org
- 为什么 Windows 上的 cmd.exe shell 使用正斜杠 ('/) 路径分隔符的路径会失败?,stackoverflow.com
在延迟扩展模式下,可以使用 % 和 ! 的组合来模拟数组,以指示变量。其中,%i% 是变量 i 的值,使用立即扩展,而 !i! 是变量 i 的值,使用延迟扩展。
@echo off
setlocal EnableDelayedExpansion
for /l %%i in (1, 1, 10) do (
set array_%%i=!random!
)
for /l %%i in (1, 1, 10) do (
echo !array_%%i!
)
:: For each item in the array, not knowing the length
set i=1
:startloop
if not defined array_%i% goto endloop
set array_%i%=!array_%i%!_dummy_suffix
echo A%i%: !array_%i%!
set /a i+=1
goto startloop
:endloop
链接
- cmd.exe(批处理)脚本中的数组、链接列表和其他数据结构,stackoverflow.com
一些任务可以通过 Perl 单行命令方便地完成。Perl 是一种源自其他操作系统的环境的脚本语言。由于许多 Windows 计算环境都安装了 Perl,因此 Perl 单行命令是 Windows 批处理脚本的自然且紧凑的扩展。
示例
- echo "abcbbc"| perl -pe "s/a.*?c/ac/"
- 让 Perl 充当 sed,该实用程序支持使用正则表达式指定的文本替换。
- echo a b| perl -lane "print $F[1]"
- 让 Perl 充当 cut 命令,显示该行的第 2 个字段或列,在本例中为 b。使用 $F[2] 显示第 3 个字段;索引从零开始。原生解决方案:FOR /f。
- perl -ne "print if /\x22hello\x22/" file.txt
- perl -ne "$. <= 10 and print" MyFile.txt
- 让 Perl 充当 head -10 命令,输出文件的前 10 行。
- perl -e "sleep 5"
- 等待 5 秒。
- for /f %i in ('perl -MPOSIX -le "print strftime '%Y-%m-%d', localtime"') do @set isodate=%i
- 以 ISO 格式获取当前日期到 isodate 变量中。
- perl -MWin32::Clipboard -e "print Win32::Clipboard->Get()"
- 输出剪贴板的文本内容。存储到 getclip.bat 时,会生成一个方便的 getclip 命令来补充 CLIP 命令。
- perl -MText::Diff -e "print diff 'File1.txt', 'File2.txt'"
- 以类似于其他操作系统中已知的 diff 命令的格式输出两个文件之间的差异,包括上下文行、以 + 开头的行和以 - 开头的行。
- perl -MWin32::Sound -e "Win32::Sound::Play('C:\WINDOWS\Media\notify.wav');"
- 播放 notify.wav 中的通知声音,不显示任何窗口。
在网络上,Perl 单行命令通常以其他操作系统的命令行约定发布,包括使用撇号 (') 而不是 Windows 引号来包围参数。这些需要针对 Windows 进行调整。
链接
Windows cmd.exe 命令解释器可以使用来自类 Unix 操作系统的命令,前提是已安装这些命令。示例命令包括 grep、sed、awk、wc、head 和 tail。这些命令来自 GNU 项目,并且存在它们的 Windows 端口。您可以在 Unix 指南 Wikibook 中了解更多关于这些命令的信息。请注意,依赖于这些命令的批处理程序不能保证在其他 Windows 机器上运行。
可以从以下项目中获得免费许可的 Windows 版本的 GNU 命令
- GnuWin32,sourceforge.net
- ezwinports,sourceforge.net:有一些比 GnuWin32 更新的端口
在 Windows 10 上运行 GNU 命令的另一种方法是 Windows 子系统 Linux。
没有其他操作系统中常见的 touch 命令。touch 命令将在不更改文件内容的情况下修改文件的上次修改时间戳。
一种解决方法,其可靠性和跨不同 Windows 版本的适用性尚不清楚,如下所示
- copy /b file.txt+,,
链接
- Windows 递归 touch 命令 在 superuser.com 上
- Unix touch 命令的 Windows 版本 在 stackoverflow.com 上
没有内置命令来获取文件的最后几行;没有 tail 命令的等价物。但是,可以编写批处理来完成这项工作,并且可以从下面的链接获得。或者,可以为 Windows 安装 tail 命令,或者运行不需要安装的 PowerShell 等价物。
链接
- CMD.EXE 批处理脚本以显示 txt 文件中的最后 10 行,stackoverflow.com
没有预安装的十六进制转储工具来查看文件内容的十六进制表示。尽管如此,还有以下选项
1) 使用fsutil file createnew 创建一个全零字节的文件,并使用fc 通过比较来查看字节
- fsutil file createnew allzeros.bin 1000
fc /b C:\Windows\notepad.exe allzeros.bin- 在比较中不会显示 notepad.exe 的零字节,但其他字节将显示其偏移量,每行一个字节。您可以通过选择全零字节文件的长度来确定要查看多少个初始字节,方法是更改上面的最后一个 1000。要查看完整的文件,请创建与要检查的文件长度相同的全零字节文件。远非完美,但可以用作快速解决方法来查看例如 BOM 标记或使用的换行符类型。
2) 使用 certutil -encodeHex,其中 encodeHex 功能未正式记录
- certutil -encodeHex file.txt filehex.txt
- 将 file.txt 的文件内容以十六进制写入 filehex.txt。如果 filehex.txt 存在,则拒绝覆盖它。您无法限制要转换的字节数。
3) 使用 PowerShell 5.0 Format-Hex
- powershell Format-Hex C:\Windows\notepad.exe
- 在最新的 PowerShell 中支持 Option -Count。
4) 安装一个命令,例如功能丰富的od 或hexdump;见 Unix 命令。od 也可以进行八进制转储。
5) 如果您使用的是旧版 32 位 Windows(不太可能),请使用debug;见 DEBUG。
链接
- fc,docs.microsoft.com
- certutil,ss64.com
- certutil,docs.microsoft.com
- Format-Hex,docs.microsoft.com
- Dave Benham 的 HEXDUMP.BAT 版本 2.1 使用 CERTUTIL,dostips.com
- 新函数 - :hexDump 由 Dave Benham,dostips.com - 纯批处理;大量的批处理魔法,而且速度很慢
如果您的用户具有提升的管理权限,则可以在以特定方式启动 cmd.exe 时使用这些权限。要以提升的权限启动 cmd.exe,您可以执行以下操作。
- 选择“开始”菜单,并在其中键入“cmd.exe”。
- 右键单击 cmd.exe 图标,然后选择“以管理员身份运行”。
要测试您是否具有提升的权限
- 运行“net session”,如果您没有权限,则此命令将失败。
限制包括以下内容
- 没有 while 循环;可以通过标签和 goto 模拟。有一个 for 循环和一个 if 语句。
- 没有 C 语言中已知的用于循环控制的 break 和 continue 语句。
- 没有合适的自定义函数;可以使用标签、call 和 %n 参数扩展来创建自定义函数。
- 对包含特殊字符(如引号(")或&号(&))的字符串进行脆弱的处理。
- 不支持数组;可以有限地进行模拟。
- 不支持关联数组,也称为字典。
- 不支持浮点运算。
- 不支持 C 语言中的三元条件运算符。
- 没有将字符转换为其 ASCII 值或将 ASCII 值转换为字符的函数。没有合理的变通方法。
- 不支持任意大小的整数运算。
- 不支持来自其他操作系统的更改文件时间戳的 touch 命令;也不支持 head 和 tail 命令。
- 不支持 GUI 编程。
- 以及更多。
这些命令都内置于命令解释器本身,无法更改。有时这是因为它们需要访问内部命令解释器数据结构,或修改命令解释器进程本身的属性。
命令 | 描述 |
---|---|
ASSOC | 将扩展名与文件类型 (FTYPE) 关联。 |
BREAK | 设置或清除扩展的 CTRL+C 检查。 |
CALL | 从另一个批处理程序调用一个批处理程序。 |
CD,CHDIR | 输出或设置当前目录。 |
CHCP | 输出或设置活动代码页编号。 |
CLS | 清除屏幕。 |
COLOR | 设置控制台的前景色和背景色。 |
COPY | 复制文件。 |
DATE | 输出并设置系统日期。 |
DEL,ERASE | 删除一个或多个文件。 |
DIR | 输出目录中的文件和子目录列表。 |
ECHO | 输出消息,或打开或关闭命令回显。 |
ELSE | 当 "IF" 不为真时,在批处理程序中执行条件处理。 |
ENDLOCAL | 结束批处理文件中环境更改的本地化。 |
EXIT | 退出 CMD.EXE 程序(命令解释器)。 |
FOR | 对一组文件中的每个文件运行指定的命令。 |
FTYPE | 设置文件类型命令。 |
GOTO | 转到标签。 |
IF | 在批处理程序中执行条件处理。 |
MD,MKDIR | 创建目录。 |
MOVE | 将文件移动到新位置 |
PATH | 设置或修改 PATH 环境 |
PAUSE | 使命令会话暂停以等待用户输入。 |
POPD | 更改为从目录堆栈中弹出的驱动器和目录 |
PROMPT | 设置或修改等待输入时显示的字符串。 |
PUSHD | 将当前目录推入堆栈,并更改为新目录。 |
RD / RMDIR | 删除目录。 |
REM | 注释命令。与双冒号 (::) 不同,该命令可以执行。 |
REN / RENAME | 重命名文件或目录。 |
SET | 设置或输出 shell 环境变量。 |
SETLOCAL | 为批处理文件创建子环境。 |
SHIFT | 将批处理参数向前移动。 |
START | 使用各种选项启动程序。 |
TIME | 输出或设置系统时钟。 |
TITLE | 更改窗口标题 |
TYPE | 将文件内容打印到控制台。 |
VER | 显示命令处理器、操作系统版本。 |
VERIFY | 验证文件复制是否已正确完成。 |
VOL | 显示当前卷的标签。 |
将扩展名与文件类型 (FTYPE) 关联,输出现有关联或删除关联。另请参阅 FTYPE。
示例
- assoc
- 列出所有关联,格式为“<文件扩展名>=<文件类型>” ,例如“.pl=Perl”或“.xls=Excel.Sheet.8”。
- assoc | find ".doc"
- 列出所有包含“.doc”子字符串的关联。
链接
在基于 Windows NT 的 Windows 版本中,不执行任何操作;保留以与 MS DOS 保持兼容性。
示例
- break > empty.txt
- 创建空文件或清除现有文件的内容,利用 break 不执行任何操作且没有输出这一事实。比“type nul > empty.txt”键入更短。
链接
从另一个批处理程序调用一个批处理程序,在单个批处理程序中调用子程序,或者,作为未记录的行为,启动程序。特别是,挂起调用者的执行,开始执行被调用者,并在被调用者完成执行时恢复调用者的执行。
有关调用子程序,请参阅 函数 部分。
请注意,在不使用 call 关键字的情况下从批处理中调用批处理会导致执行在被调用者完成时永远不会返回到调用者。
被调用者继承调用者的环境变量,并且除非被调用者通过 SETLOCAL 阻止这种情况,否则被调用者对环境变量所做的更改在恢复执行后将对调用者可见。
示例
- mybatch.bat
- 如果在批处理中使用,则将控制权转移到 mybatch.bat 并且永远不会恢复调用者的执行。
- call mybatch.bat
- call mybatch
- call mybatch.bat arg1 "arg 2"
- call :mylabel
- call :mylabel arg1 "arg 2"
- cmd /c mybatch.bat
- 类似于 call,但即使出现错误也会恢复执行。此外,被调用者对环境变量所做的任何更改都不会传播到调用者。
- call notepad.exe
- 启动记事本,或一般来说,任何其他可执行文件。这显然不是 call 的预期用法,并且没有正式记录。
链接
- ss64.com 上的 call
- Microsoft 上的 call
- CALL 命令与带有 /WAIT 选项的 START 命令,stackoverflow.com
更改到不同的目录,或输出当前目录。但是,如果使用了不同的驱动器号,它不会切换到该不同的驱动器或卷。
示例
- cd
- 输出当前目录,例如 C:\Windows\System32。
- cd C:\Program Files
- 路径中包含空格时,不需要使用引号括起来。
- cd \Program Files
- cd Documents
- cd %USERPROFILE%
- cd /d C:\Program Files
- 即使 C: 不是当前驱动器,也会更改到 C: 驱动器的目录。
- C: & cd C:\Program Files。
- 即使 C: 不是当前驱动器,也会更改到 C: 驱动器的目录。
- cd ..
- 更改到父目录。如果已经在根目录中,则不执行任何操作。
- cd ..\..
- 更改到上两级的父目录。
- C: & cd C:\Windows\System32 & cd ..\..\Program Files
- 使用“..”在目录树中向上和向下导航
- cd \\myserver\folder
- 不起作用。无法直接将目录更改为网络通用命名约定 (UNC) 文件夹。关键字:UNC 路径。
- subst A: \\myserver\folder && cd /d A
- 使用 #SUBST 命令将目录更改为服务器文件夹,假设驱动器号 A: 是空闲的。
- pushd \\myserver\folder
- 自动为文件夹创建驱动器并切换到该驱动器。使用#POPD后,驱动器将再次取消分配。
- cd C:\W*
- 在典型的 Windows 设置中更改为 C:\Windows。因此,通配符有效。对从命令行手动键入很有用。
- cd C:\W*\*32
- 在典型的 Windows 设置中更改为 C:\Windows\System32。
链接
是 CD 的同义词。
清除屏幕。
设置控制台的前景色和背景色。
示例
- color f9
- 使用白色背景和蓝色前景色。
- color
- 恢复原始颜色设置。
链接
复制文件。另请参阅 MOVE、XCOPY 和 ROBOCOPY。
示例
- copy F:\File.txt
- 复制文件到当前目录,假设当前目录不是 F:\。
- copy "F:\My File.txt"
- 同上;需要用引号括住包含空格的文件名。
- copy F:\*.txt
- 将位于 F:\ 且以 .txt 结尾的文件复制到当前目录,假设当前目录不是 F:\。
- copy F:\*.txt .
- 与上一条命令相同。
- copy File.txt
- 显示错误消息,因为 File.txt 不能覆盖自身。
- copy File1.txt File2.txt
- 将 File1.txt 复制到 File2.txt,如果用户确认或从批处理脚本运行则覆盖 File2.txt。
- copy File.txt "My Directory"
- 将 File.txt 复制到 "My Directory" 目录,假设 "My Directory" 目录存在。
- copy Dir1 Dir2
- 将目录 Dir1 中直接位于该目录下的所有文件复制到 Dir2,假设 Dir1 和 Dir2 都是目录。不会复制 Dir1 的嵌套目录中的文件。
- copy *.txt *.bak
- 对于当前文件夹中的每个 *.txt 文件,创建一个以 "bak" 而不是 "txt" 结尾的副本。
链接
删除文件。谨慎使用,尤其是在与通配符结合使用时。仅删除文件,不删除目录,有关目录的删除,请参阅 RD。更多信息,请键入 "del /?"。
示例
- del File.txt
- del /s *.txt
- 递归删除文件,包括嵌套目录,但保留目录;无情地删除所有匹配的文件,无需确认。
- del /p /s *.txt
- 同上,但在删除每个文件之前都要求确认。
- del /q *.txt
- 删除文件,无需确认。
链接
列出目录的内容。提供一系列选项。键入 "dir /?" 获取更多帮助。
示例
- dir
- 列出当前文件夹中的文件和文件夹,不包括隐藏文件和系统文件;如果 DIRCMD 变量非空且包含 dir 的开关,则使用不同的列出方式。
- dir D
- dir /b C:\Users
- dir /s
- 递归列出目录及其所有子目录的内容。
- dir /s /b
- 递归列出目录及其所有子目录的内容,每行一个文件,显示每个列出的文件或目录的完整路径。
- dir *.txt
- 列出所有扩展名为 .txt 的文件。
- dir /a
- 在列表中包含隐藏文件和系统文件。
- dir /ah
- 仅列出隐藏文件。
- dir /ad
- 仅列出目录。/A 后面的其他字母包括 S、I、R、A 和 L。
- dir /ahd
- 仅列出隐藏目录。
- dir /a-d
- 仅列出文件,省略目录。
- dir /a-d-h
- 仅列出非隐藏文件,省略目录。
- dir /od
- 按上次修改日期对文件和文件夹进行排序。/O 后面的其他字母包括 N(按名称)、E(按扩展名)、S(按大小)和 G(文件夹优先)
- dir /o-s
- 按大小降序排列文件;对文件夹顺序的影响尚不清楚。
- dir /-c /o-s /a-d
- 列出按大小降序排列的文件,通过 /-C 省略千位分隔符,排除文件夹。
- dir /s /b /od
- 递归列出目录及其所有子目录的内容,按上次修改日期对每个目录中的文件进行排序。排序仅在每个目录中进行;如此找到的文件的完整集合不会整体排序。
- dir /a /s
- 递归列出文件,包括隐藏文件和系统文件。可以通过考虑输出的最后几行来计算磁盘使用情况(目录大小)。
链接
输出或设置日期。日期的输出方式取决于国家/地区设置。日期也可以使用 "echo %DATE%" 输出。
获取 ISO 格式的日期,例如 "2000-01-28":这并不容易,因为日期格式取决于国家/地区设置。
- 如果您可以假设格式为 "Mon 01/28/2000",则以下代码将起作用
- set isodate=%date:~10,4%-%date:~4,2%-%date:~7,2%
- 如果您有 WMIC,则以下代码与区域设置无关
- for /f %i in ('wmic os get LocalDateTime') do @if %i lss a if %i gtr 0 set localdt=%i
set isodate=%localdt:~0,4%-%localdt:~4,2%-%localdt:~6,2% - 要在批处理中使用上述代码,请将 %i 更改为 %%i 并从 if 前面的 @ 中删除 @。
- for /f %i in ('wmic os get LocalDateTime') do @if %i lss a if %i gtr 0 set localdt=%i
- 如果您安装了 Perl
- for /f %i in ('perl -MPOSIX -le "print strftime '%Y-%m-%d', localtime"') do @set isodate=%i
链接
- date 在 ss64.com 上
- date 在 Microsoft 上
- 如何在 Windows 命令行中获取当前日期时间,并以适合用作文件名格式的格式输出? 在 stackoverflow 上
输出消息,或打开或关闭命令回显。
示例
- echo on
- @echo off
- echo Hello
- echo "hello"
- 也输出引号。
- echo %PATH%
- 输出 PATH 变量的内容。
- echo Owner ^& son
- 使用脱字符 (^) 转义与号 (&),从而能够回显与号。
- echo 1&echo 2&echo 3
- 输出三个字符串,每个字符串后面跟着一个换行符。
- echo.
- 输出一个换行符,而句点不被输出。如果没有句点,则输出 "echo off" 或 "echo on"。在句点前面添加一个空格会导致句点被输出。其他与句点具有相同效果的字符包括 ;:,/\(=+[].
- echo %random%>>MyRandomNumbers.txt
- 虽然它似乎将随机数输出到 MyRandomNumbers.txt,但实际上它不会对 0-9 的数字这样做,因为这些数字放在 >> 前面时,表示要重定向哪个通道。另请参阅 #Redirection。
- echo 2>>MyRandomNumbers.txt
- 不回显 2,而是将标准错误重定向到文件。
- (echo 2)>>MyRandomNumbers.txt
- 即使是小的数字(在本例中为 2)也会回显并重定向结果。
- >>MyRandomNumbers.txt echo 2
- 另一种回显即使是小的数字并重定向结果的方法。
显示不带换行符的字符串需要一个技巧
- set <NUL /p=Output of a command
- 输出 "Output of a command:"。下一个命令的输出将紧跟在 ":" 后面显示。
- set <NUL /p=Current time: & time /t
- 输出 "Current time: " 后跟 "time /t" 的输出。
- (set <NUL /p=Current time: & time /t) >tmp.txt
- 与之前一样,将两个命令的输出都重定向到文件。
链接
一个例子
if exist file.txt (
echo The file exists.
) else (
echo The file does not exist.
)
另请参阅 IF。
结束使用 SETLOCAL 启动的本地环境变量集。可用于创建子程序:请参阅 Functions。
链接
DEL 的同义词。
退出 DOS 控制台,或者使用 /b 仅退出当前运行的批处理或当前执行的子例程。如果在批处理文件中不带 /b 使用,则会导致调用批处理的 DOS 控制台关闭。
示例
- exit
- exit /b
链接
迭代一系列值,执行命令。关键字:循环。
在以下示例中,%i 用于命令行,而 %%i 用于批处理。索引(例如,%i)必须是单字符变量名。
不带开关和带 /r 和 /d 开关的示例
- for %%i in (1,2,3) do echo %%i
- 在批处理中,回显 1、2 和 3。在批处理中,命令必须使用双百分号。
- 其余示例旨在直接粘贴到命令行中,因此它们使用单个百分号并包含 "@" 以防止重复显示。
- for %i in (1,2,3) do @echo %i
- 从命令行回显 1、2 和 3。
- for 命令尝试将项目解释为文件名和包含通配符的文件名模式。
- 但是,如果项目与现有文件名不匹配,它不会报错。
- for %i in (1,2,a*d*c*e*t) do @echo %i
- 除非您碰巧有一个与第三个模式匹配的文件,否则回显 1 和 2,丢弃第三个项目。
- for %i in (1 2,3;4) do @echo %i
- 回显 1、2、3 和 4。是的,使用了项目分隔符的混合。
- for %i in (*.txt) do @echo %i
- 回显位于当前文件夹中且扩展名为 .txt 的文件的文件名。
- for %i in ("C:\Windows\system32\*.exe") do @echo %i
- 回显与模式匹配的文件名。
- for /r %i in (*.txt) do @echo %i
- 回显具有完整路径的文件名,这些文件扩展名为 .txt,位于当前文件夹的任何位置,包括嵌套文件夹。
- for /d %i in (*) do @echo %i
- 回显当前文件夹中所有文件夹的名称。
- for /r /d %i in (*) do @echo %i
- 回显当前文件夹中所有文件夹(包括嵌套文件夹)的名称,包括完整路径。
- for /r %i in (*) do @if %~zi geq 1000000 echo %~zi %i
- 对于当前文件夹及其子文件夹中大小大于或等于 1,000,000 字节的每个文件,输出文件大小(以字节为单位)和文件的完整路径。有关 %~zi 中的语法,请参阅 #百分号波浪线。
/l 开关的示例
- for /l %i in (1,2,11) do @echo %i
- 以步长为 2,输出从 1 到 11 的数字。格式为 (起始值, 步长, 结束值)。支持 32 位有符号整数。
- for /l %i in (10,-1,1) do @echo %i
- 输出从 10 到 1 的降序数字。
- for /l %i in (1,0,1) do @echo %i
- 持续输出 1;一个无限循环。
- for /l %i in (0) do @echo %i
- 持续输出 0;一个无限循环。
- for /l %i in () do @echo %i
- 持续输出 0;一个无限循环。
- for /l %i in (-10,1) do @echo %i
- 输出从 -10 到 0 的数字;未明确指定的结束值默认为零。
- for /l %i in (0xF, 1, 020) do @echo %i
- 输出从 15 到 16 的数字;因此,支持十六进制和八进制字面量。
- for /l %i in (2147483646,1,2147483647) do @echo %i
- 输出 2147483646,然后 2147483647,然后 -2147483648,然后 -2147483647,依此类推。这可能是由于 2147483647 的增量溢出到 -2147483648 造成的。
- for /l %i in (-2147483648,1,-2147483647) do @echo %i
- 输出 -2147483648 和 -2147483647。因此,直接支持 -2147483648 字面量,不像 set /a。
/f 开关的示例
- for /f "tokens=*" %i in (list.txt) do @echo %i
- 对于文件中的每一行,输出该行。
- for /f "tokens=*" %i in (list1.txt list2.txt) do @echo %i
- 对于文件中的每一行,输出该行。
- for /f "tokens=*" %i in (*.txt) do @echo %i
- 不执行任何操作。不接受用于匹配文件名的通配符。
- for /f "tokens=1-3 delims=:" %a in ("First:Second::Third") do @echo %c-%b-%a
- 将字符串解析为以“:”分隔的标记。
- 引号表示该字符串不是文件名。
- 即使在命令的“do”之前的部分没有明确提及 %b 和 %c,第二个和第三个标记也会存储在 %b 和 %c 中。
- 两个连续的冒号被视为一个分隔符;%c 不是 "",而是 "Third"。
- 执行其他操作系统中 cut 命令的部分功能。
- for /f "tokens=1-3* delims=:" %a in ("First:Second::Third:Fourth:Fifth") do @echo %c-%b-%a: %d
- 与上面相同,只是第 4 和第 5 个项目被捕获到 %d 中,包括分隔符,即 "Fourth:Fifth"。
- for /f "tokens=1-3* delims=:," %a in ("First,Second,:Third:Fourth:Fifth") do @echo %c-%b-%a: %d
- 可以有多个分隔符。
- for /f "tokens=1-3" %a in ("First Second Third,item") do @echo %c-%b-%a
- 默认分隔符是空格和制表符。因此,它们与传递给批处理的参数的分隔符不同。
- for /f "tokens=*" %i in ('cd') do @echo %i
- 对于命令结果的每一行,输出该行。
- for /f "tokens=*" %i in ('dir /b /a-d-h') do @echo %~nxai
- 对于当前文件夹中的每个非隐藏文件,输出文件属性,后跟文件名。在字符串 "%~nxai" 中,使用 #Percent tilde 中描述的语法。
- for /f "usebackq tokens=*" %i in (`dir /b /a-d-h`) do @echo %~nxai
- 与上面相同,但使用反引号字符 (`) 将要执行的命令括起来。
- for /f "tokens=*" %i in ('tasklist ^| sort ^& echo End') do @echo %i
- 要执行的命令中的管道和与号必须使用脱字符 (^) 进行转义。
重定向示例
- (for %i in (1,2,3) do @echo %i) > anyoldtemp.txt
- 要重定向 for 循环的整个结果,请在重定向之前将整个循环放在括号中。否则,重定向将绑定到循环体,因此循环体的每次新迭代都将覆盖先前迭代的结果。
- for %i in (1,2,3) do @echo %i > anyoldtemp.txt
- 与上面相关的示例。它显示了未将循环放在括号中的后果。
继续: 要跳转到循环的下一轮迭代并模拟许多语言中已知的 continue 语句,您可以使用 goto,前提是您将循环体放在一个子例程中,如下所示
for %%i in (a b c) do call :for_body %%i
exit /b
:for_body
echo 1 %1
goto :cont
echo 2 %1
:cont
exit /b
如果您直接在 for 循环内部使用 goto,则 goto 的使用会破坏循环簿记。以下操作失败
for %%i in (a b c) do (
echo 1 %%i
goto :cont
echo 2 %%i
:cont
echo 3 %%i
)
链接
- for 在 ss64.com 上
- Microsoft 上的 for
- CMD.EXE 解析数字的规则,作者 dbenham,dostips.com
输出或设置要为文件类型执行的命令。另请参见 ASSOC。
示例
- ftype
- 列出所有与文件类型关联的要执行的命令,例如“Perl="C:\Perl\bin\perl.exe" "%1" %*”
- ftype | find "Excel.Sheet"
- 仅列出显示行包含“Excel.Sheet”的关联。
链接
转到标签。
一个例子
goto :mylabel
echo Hello 1
REM Hello 1 never gets printed.
:mylabel
echo Hello 2
goto :eof
echo Hello 3
REM Hello 3 never gets printed. Eof is a virtual label standing for the end of file.
在 for 循环体中使用 goto 会使 cmd 忘记循环,即使标签在同一个循环体中。
链接
有条件地执行命令。通过在 CMD 提示符下输入 IF /? 可以查看文档。
可用的基本测试
- exist <文件名>
- <字符串>==<字符串>
- <表达式1> equ <表达式2> -- 等于
- <表达式1> neq <表达式2> -- 不等于
- <表达式1> lss <表达式2> -- 小于
- <表达式1> leq <表达式2> -- 小于或等于
- <表达式1> gtr <表达式2> -- 大于
- <表达式1> geq <表达式2> -- 大于或等于
- defined <变量>
- errorlevel <数字>
- cmdextversion <数字>
可以对每个基本测试应用“not”。显然,没有像 AND、OR 等运算符来组合基本测试。
/I 开关使 == 和 equ 比较忽略大小写。
一个例子
if not exist %targetpath% (
echo Target path not found.
exit /b
)
示例
- if not 1 equ 0 echo Not equal
- if 1 equ 0 echo A & echo B
- 不执行任何操作;两个 echo 命令都受条件约束。
- if not 1 equ 0 goto :mylabel
- if not a geq b echo Not greater
- if b geq a echo Greater
- if b geq A echo Greater in a case-insensitive comparison
- if B geq a echo Greater in a case-insensitive comparison
- if 0 equ 00 echo Numerical equality
- if not 0==00 echo String inequality
- if 01 geq 1 echo Numerical comparison
- if not "01" geq "1" echo String comparison
- if 1 equ 0 (echo Equal) else echo Unequal
- 注意 then 部分周围的括号,以使其正常工作。
- if not a==A echo Case-sensitive inequality
- if /i a==A echo Case-insensitive equality
- if /i==/i echo This does not work
- if "/i"=="/i" echo Equal, using quotation marks to prevent the literal meaning of /i
链接
创建新目录或目录。具有同义词 MKDIR;另请参见其反义词 RD。
示例
- md Dir
- 在当前目录中创建一个目录。
- md Dir1 Dir2
- 在当前目录中创建两个目录。
- md "My Dir With Spaces"
- 在当前目录中创建名称包含空格的目录。
链接
MD 的同义词。
创建符号链接或其他类型的链接。自 Windows Vista 起可用。
链接
在目录之间移动文件或目录,或重命名它们。另请参见 REN。
示例
- move File1.txt File2.txt
- 将 File1.txt 重命名为 File2.txt,如果用户确认或从批处理脚本运行,则覆盖 File2.txt。
- move File.txt Dir
- 将 File.txt 文件移动到 Dir 目录中,假设 File.txt 是文件,Dir 是目录;如果满足覆盖条件,则覆盖目标文件 Dir\a.txt。
- move Dir1 Dir2
- 将目录 Dir1 重命名为 Dir2,假设 Dir1 是目录,Dir2 不存在。
- move Dir1 Dir2
- 将目录 Dir1 移动到 Dir2 中,导致 Dir2\Dir1 存在,假设 Dir1 和 Dir2 都是现有目录。
- move F:\File.txt
- 将文件移动到当前目录。
- move F:\*.txt
- 将位于 F:\ 并以点 txt 结尾的文件移动到当前目录,假设当前目录不是 F:\。
链接
输出或设置 PATH 环境变量的值。输出时,在输出的开头包含“PATH=”。
示例
- path
- 输出 PATH。示例输出
- PATH=C:\Windows\system32;C:\Windows;C:\Program Files\Python27
- 输出 PATH。示例输出
- path C:\Users\Joe Hoe\Scripts;%path%
- 将 C:\Users\Joe Hoe\Scripts 扩展到路径,仅适用于 cmd.exe 进程。
- path ;
- 清空路径。
- echo %path% | perl -pe "s/;/\n/g" | sort
- 如果安装了 perl,则显示路径中排序的文件夹。
链接
提示用户并等待输入一行。
链接
更改驱动器和从目录堆栈弹出的目录。目录堆栈使用PUSHD命令填充。
链接
可用于更改或重置cmd.exe提示符。它设置PROMPT环境变量的值。
C:\>PROMPT MyPrompt$G
MyPrompt>CD
C:\
MyPrompt>PROMPT
C:\>
PROMPT命令用于将提示符设置为“MyPrompt>”。CD显示当前目录路径为“C:\”。不带任何参数使用PROMPT会将提示符恢复为目录路径。
链接
将当前目录推入目录堆栈,使其可供POPD命令检索,并且如果执行时带有参数,则更改为作为参数指定的目录。
链接
删除目录。另请参见其同义词RMDIR和反义词MD。默认情况下,只能删除空目录。还可以键入“rd /?”。
示例
- rd Dir1
- rd Dir1 Dir2
- rd "My Dir With Spaces"
- rd /s Dir1
- 删除目录Dir1,包括其中的所有文件和子目录,在继续删除之前会先询问一次是否确认。要递归删除嵌套目录中的文件并针对每个文件进行确认,请使用带/s开关的DEL。
- rd /q /s Dir1
- 与上面类似,但不询问是否确认。
链接
重命名文件和目录。
示例
- ren filewithtpyo.txt filewithtypo.txt
- ren *.cxx *.cpp
链接
- ss64.com上的ren
- Microsoft上的ren
- Windows RENAME命令如何解释通配符?,superuser.com
这是REN命令的同义词。
用于批处理文件中的注释,防止执行注释内容。
一个例子
REM A remark that does not get executed
echo Hello REM This remark gets displayed by echo
echo Hello & REM This remark gets ignored as wished
:: This sentence has been marked as a remark using double colon.
REM通常放置在一行的开头。如果放置在命令后面,则不起作用,除非前面有与号,如上例所示。
双冒号是REM的替代方法。当在括号中序列的中间使用时,它可能会导致问题,例如在FOR循环中使用的那些。双冒号似乎只是一个技巧,一个以冒号开头的标签。
链接
- ss64.com上的rem
- Microsoft上的rem
- 在批处理文件中我应该使用哪种注释样式?,stackoverflow.com
这是RD的同义词。
输出或设置环境变量。使用/P开关,它会提示用户输入,并将结果存储在变量中。使用/A开关,它会执行简单的算术运算,并将结果存储在变量中。对于字符串赋值,通常避免等号前后有空格,因为它们会导致通常不希望出现的结果:“set name = Peter”将赋值给变量“name ”,而“set name=Peter”将赋值给变量“name”。另请参见#环境变量和#计算。
示例
- set
- 以VAR=VALUE的格式输出环境变量及其值的列表,每行一个变量。
- set home
- 以VAR=VALUE的格式输出名称以“home”开头的变量的环境变量及其值的列表(不区分大小写),每行一个变量。
- set HOME
- 如上所述;变量名称前缀和变量名称之间的匹配不区分大小写。
- set myname=Joe Hoe
- 将变量设置为新值。
- set mynumber=56
- 将变量设置为“56”的字符串值。
- set mynumber=
- 取消设置变量,将其从变量中删除。等号(=)必须是最后一个字符;如果等号后面有任何空格,它们将成为变量的新值。
- set home=%home%;C:\Program Files\My Bin Folder
- set /P user_input=Enter an integer
- set /P firstline=< File.txt
- 将变量设置为文件的第一行。其他操作系统的head -1命令的等效项。
- set /A result = 4 * ( 6 / 3 )
- 使用计算结果设置result变量。另请参见#计算。
- set name = Peter
echo *%name %*- 将变量“name ”(末尾带空格)的值设置为“ Peter”(开头带空格)。目的可能是使用“set name=Peter”,不带分隔空格。
链接
在批处理文件中使用时,会使对环境变量的所有进一步更改都对当前批处理文件本地化。在批处理文件外部使用时,不执行任何操作。可以使用ENDLOCAL结束。退出批处理文件会自动调用“end local”。可用于创建子程序:请参见函数。
此外,还可以使用它来启用延迟扩展,例如:“setlocal EnableDelayedExpansion”。延迟扩展包括变量名称括在感叹号中,仅在执行到达其使用位置后才替换为其值,而不是在更早的点替换。
以下是在脚本中使用延迟扩展的示例,该脚本打印文件的指定数量的第一行,提供其他操作系统中已知的“head”命令的部分功能
@echo off
call :myhead 2 File.txt
exit /b
:: Function myhead
:: ===============
:: %1 - lines count, %2 - file name
:myhead
setlocal EnableDelayedExpansion
set counter=1
for /f "tokens=*" %%i in (%2) do (
echo %%i
set /a counter=!counter!+1
if !counter! gtr %1 exit /b
)
exit /b
链接
将批处理文件参数沿其移动,但不影响%*。因此,如果%1=Hello 1,%2=Hello 2,%3=Hello 3,则在SHIFT之后,%1=Hello 2,%2=Hello 3,但%*为“Hello 1” “Hello 2” “Hello 3”。
链接
在新窗口中启动程序或打开文档。使用一种不清楚的算法来确定传递的第一个参数是窗口标题还是要执行的程序;假设:它使用第一个参数周围是否存在引号作为提示,表明它是窗口标题。
示例
- start notepad.exe & echo "Done."
- 启动notepad.exe,继续执行下一条命令,而无需等待已启动的命令完成。关键词:异步。
- start "notepad.exe"
- 启动一个新的控制台窗口,notepad.exe作为其标题,显然是一个不希望的结果。
- start "" "C:\Program Files\Internet Explorer\iexplore.exe"
- 启动Internet Explorer。作为第一个参数传递的空""是实际上未打开的控制台的窗口标题,或者至少不是可见的。
- start "C:\Program Files\Internet Explorer\iexplore.exe"
- 启动一个新的控制台窗口,"C:\Program Files\Internet Explorer\iexplore.exe"作为其标题,显然是一个不希望的结果。
- start /wait notepad.exe & echo "Done."
- 启动notepad.exe,等待其结束后再继续。
- start /low notepad.exe & echo "Done."
- 如上所述,但以低优先级启动程序。
- start "" MyFile.xls
- 在分配打开它的程序中打开文档。
- start
- 在相同的当前文件夹中启动一个新的控制台(命令行窗口)。
- start .
- 在Windows资源管理器中打开当前文件夹。
- start ..
- 在Windows资源管理器中打开父文件夹。
- start "" "mailto:"
- 启动编写新电子邮件的应用程序。
- start "" "mailto:[email protected]?subject=Notification&body=Hello Joe, I'd like to..."
- 启动编写新电子邮件的应用程序,指定新电子邮件的收件人、主题和正文。
- start "" "mailto:[email protected]?subject=Notification&body=Hello Joe,%0a%0aI'd like to..."
- 如上所述,使用%0a输入换行符。
- start /b TODO:example-application-where-this-is-useful
- 启动应用程序而不打开新的控制台窗口,将输出重定向到调用start命令的控制台。
链接
- ss64.com上的start
- Microsoft上的start
- 如何在Outlook中使用命令行开关创建预先设置地址的电子邮件?,support.microsoft.com
输出或设置系统时间。另请参见#DATE以及#特殊变量名称中的TIME变量。
示例
- time /t
- 以HH:MM格式输出系统时间,不显示秒和毫秒。例如输出:09:19。
- time
- 以特定于区域设置的格式输出系统时间,可能包含秒和百分之一秒,并提示输入新的时间进行设置;时间前面带有特定于区域设置的消息,通常是“当前时间:”的翻译。因此,输出格式与“time /t”的输出格式不同。
- echo %time%
- 使用特殊变量TIME输出当前时间,以特定于区域设置的格式显示小时、分钟、秒,以及可能包含的百分之一秒。例如,在一个区域设置中的输出:9:19:31.55。
- echo %time% & timeout 1 >nul & echo,|time
- 在中间的命令(此处为timeout 1)前后输出时间。可用于测量中间序列的执行时间;关键词:需要多长时间。
链接
设置在控制台窗口中显示的标题。
链接
将文件或文件的内容打印到输出。
示例
- type filename.txt
- type a.txt b.txt
- type *.txt
- type NUL > tmp.txt
- 创建空文件(空白文件)。
链接
显示命令处理器或操作系统版本。
C:\>VER
Microsoft Windows XP [Version 5.1.2600]
C:\>
一些版本字符串
- Microsoft Windows [版本 5.1.2600]
- 适用于Windows XP
- Microsoft Windows [版本 6.0.6000]
- 适用于Windows Vista
- ...
“版本”一词是本地化的。
链接
- ver 在ss64.com
- ver 在Microsoft
- 操作系统版本在Microsoft
- Microsoft Windows版本列表,wikipedia.org
- Windows 内部版本号,eddiejackson.net
- mxpv/windows_build_numbers.txt,gist.github.com
设置或清除设置,以验证是否正确写入COPY文件等。
链接
输出卷标。
链接
Windows 命令解释器可用的外部命令是单独的可执行程序文件,由 Microsoft 提供操作系统,或作为第三方命令解释器的标准捆绑包提供。通过替换程序文件,可以更改这些命令的含义和功能。
许多(但并非所有)外部命令都支持“/?”约定,这会导致它们将其联机使用信息写入标准输出,然后以状态代码0退出。
输出或更改地址解析协议缓存中的项目,该缓存将 IP 地址映射到物理地址。
链接
计划在特定时间运行程序。另请参见SCHTASKS。
链接
输出或设置文件属性。在没有参数的情况下,它将输出当前目录中所有文件的属性。在没有属性修改指令的情况下,它将输出与给定搜索通配符规范匹配的文件和目录的属性。类似于其他操作系统的chmod。
修改指令
- 要添加属性,请在其字母前附加“+”。
- 要删除属性,请在其字母前附加“-”。
- 属性
- A - 存档
- H - 隐藏
- S - 系统
- R - 只读
- …以及其他一些。
示例
- attrib
- 输出当前目录中所有文件的属性。
- attrib File.txt
- 输出文件的属性。
- attrib +r File.txt
- 向文件添加“只读”属性。
- attrib -a File.txt
- 从文件删除“存档”属性。
- attrib -a +r File.txt
- 删除“存档”属性并向文件添加“只读”属性。
- attrib +r *.txt
- 作用于一组文件。
- attrib /S +r *.txt
- 在子目录中递归地执行操作。
更多信息,请键入“attrib /?”。
链接
(XP中没有)。编辑启动配置数据 (BCD) 文件。更多信息,请键入“bcdedit /?”。
链接
输出或更改任意访问控制列表 (DACL)。另请参见ICACLS。更多信息,请键入“cacls /?”。
链接
输出或设置活动代码页编号。更多信息,请键入“chcp /?”。
链接
检查磁盘是否存在磁盘问题,列出它们,并在需要时修复它们。更多信息,请键入“chkdsk /?”。
链接
显示或设置是否应在计算机启动时运行系统检查。系统检查使用Autochk.exe完成。“NTFS”命令名称的一部分具有误导性,因为该命令不仅适用于NTFS文件系统,也适用于FAT和FAT32文件系统。更多信息,请键入“chkntfs /?”。
链接
允许用户通过按单个键选择多个选项之一,并根据所选选项设置错误级别。在Windows 2000和Windows XP中不存在,它在Windows Vista中重新引入,并在Windows 7和8中保留。
示例
- choice /m "您同意吗"
- 向用户显示一个是/否问题,对于是,错误级别设置为1,对于否,错误级别设置为2。如果用户按下Control + C,则错误级别为0。
- choice /c rgb /m "您更喜欢哪种颜色"
- 向用户显示一个问题,并指示用户的字母。响应用户按下r、g或b,错误级别设置为1、2或3。
另一种方法是“set /p”;请参见SET。
链接
显示加密状态,加密或解密NTFS卷上的文件夹。
链接
(XP中没有,或从Server 2003复制)将管道输入放置到剪贴板。
示例
- set | clip
- 将环境变量列表放置到剪贴板。
- clip < File1.txt
- 将File1.txt的内容放置到剪贴板。
链接
调用另一个 Microsoft CMD 实例。
链接
比较文件。另请参阅 FC。
链接
显示或更改 NTFS 分区上文件或文件夹的压缩方式。
链接
将卷从 FAT16 或 FAT32 文件系统转换为 NTFS 文件系统。
链接
允许以交互方式检查文件和内存内容,以汇编语言、十六进制或 ASCII 格式显示。适用于 32 位 Windows(包括 Windows 7);在 64 位 Windows 中的可用性尚不清楚。在现代 Windows 中,可作为快速查看文件十六进制内容的工具。关键词:十六进制转储、hexdump、十六进制转储、查看十六进制、查看十六进制、反汇编程序。
Debug 提供了自己的命令行。在命令行中,键入“?”以查找有关调试命令的信息。
要查看文件的十六进制内容,请使用文件名作为参数调用 debug.exe,然后在调试命令行中重复键入“d”并按 Enter 键。
限制
- 作为 DOS 程序,debug 无法处理长文件名。使用 dir /x 查找 8.3 文件名,然后对该文件名应用 debug。
- Debug 无法查看较大的文件。
链接
- 适用于 Windows XP 的 Debug,来自 TechNet/Microsoft 文档
- 适用于 MS-DOS 的 Debug,来自 TechNet/Microsoft 文档
- W:Debug(命令)
比较两张软盘的内容。
链接
将一张软盘的内容复制到另一张软盘。
链接
显示和配置磁盘分区的属性。
链接
最重要的是,创建其他操作系统中称为别名的宏。此外,还提供与命令历史记录和增强型命令行编辑相关的功能。宏是简短批处理脚本的替代方案。
与宏相关的示例
- doskey da=dir /s /b
- 创建一个名为“da”的单个宏
- doskey np=notepad $1
- 创建一个将第一个参数传递给记事本的单个宏。
- doskey /macrofile=doskeymacros.txt
- 从文件中加载宏定义。
- doskey /macros
- 列出所有已定义的宏及其定义。
- doskey /macros | find "da"
- 列出所有包含“da”作为子字符串的宏定义;另请参阅 FIND。
与命令历史记录相关的示例
- doskey /history
- 列出完整的命令历史记录。
- doskey /history | find "dir"
- 列出命令历史记录中每个包含“dir”作为子字符串的行
- doskey /listsize=100
- 将命令历史记录的大小设置为 100。
要从命令行获取 doskey 的帮助,请键入“doskey /?”。
链接
显示所有已安装的设备驱动程序及其属性。
链接
从压缩的 .cab 压缩包文件中提取文件。另请参阅 #MAKECAB。
链接
比较文件,以一种特殊的方式显示其内容的差异。
示例
- fc File1.txt File2.txt >NUL && Echo Same || echo Different or error
- 使用 fc 的错误级别检测差异。错误级别为零表示文件相同;非零可能表示文件不同,也可能表示其中一个文件不存在。
链接
搜索文件或输入、输出中是否存在字符串,输出匹配的行。与 FINDSTR 不同,它不能递归搜索文件夹,不能搜索正则表达式,需要在搜索字符串周围加上引号,并且将空格视为字面意义上的空格,而不是逻辑或。
示例
- find "(object" *.txt
- dir /S /B | find "receipt"
- dir /S /B | find /I /V "receipt"
- 打印 dir 命令输出中所有不匹配的行,忽略字母大小写。
- find /C "inlined" *.h
- 不输出匹配的行,而是输出其计数。如果搜索多个文件,则每个文件前面都有一系列破折号,后面跟着文件名;不输出所有文件中匹配行的总数。
- find /C /V "" < file.txt
- 输出“file.txt”中的行数,也称为行计数。执行其他操作系统中“wc -l”的功能。通过将“”视为行中找不到的字符串来工作。重定向的使用防止文件名在行数之前输出。
- type file.txt | find /C /V ""
- 与上面类似,但语法不同。
- type *.txt 2>NUL | find /C /V ""
- 输出当前文件夹中以“.txt”结尾的文件的行数总和。“2>NUL”是标准错误的重定向,它从输出中删除了文件名称后跟空行的内容。
- find "Schönheit" *.txt
- 如果从以 unicode UTF-8 编码保存的批处理文件中运行,则会在 UTF-8 编码的 *.txt 文件中搜索搜索词“Schönheit”。要使此功能正常工作,批处理文件不得包含记事本在以 UTF-8 编码保存时写入的字节顺序标记。Notepad++ 是一个可以让你编写不带字节顺序标记的 UTF-8 编码纯文本文件的程序示例。虽然这对 find 命令有效,但对 #FINDSTR 无效。
- find "Copyright" C:\Windows\system32\a*.exe
- 不仅适用于文本文件,也适用于二进制文件。
链接
在文件中搜索正则表达式或文本字符串。执行其他操作系统中称为“grep”命令的一些功能,但在其支持的正则表达式方面要有限得多。
除非使用 /c 选项阻止,否则将正则表达式中的空格视为析取,也称为逻辑或。
示例
- findstr /s "[0-9][0-9].*[0-9][0-9]" *.h *.cpp
- 递归搜索所有以点 h 或点 cpp 结尾的文件,仅打印包含两个连续十进制数字后跟任何内容后跟两个连续十进制数字的行。
- findstr "a.*b a.*c" File.txt
- 输出 File.txt 中所有与两个由空格分隔的正则表达式中的任何一个匹配的行。因此,其效果是对正则表达式进行逻辑或操作。
- echo world | findstr "hello wo.ld"
- 不匹配。由于空格之前的第一个项目不像是正则表达式,因此 findstr 将整个搜索词视为普通搜索词。
- echo world | findstr /r "hello wo.ld"
- 匹配。使用 /r 强制进行正则表达式处理。
- findstr /r /c:"ID: *[0-9]*" File.txt
- 输出 File.txt 中所有与包含空格的单个正则表达式匹配的行。使用 /c 可以防止空格被视为逻辑或。使用 /r 会启用正则表达式处理,该处理默认情况下会被 /c 禁用。要测试这一点,请尝试以下操作
- echo ID: 12|findstr /r /c:"ID: *[0-9]*$"
- 匹配。
- echo ID: 12|findstr /c:"ID: *[0-9]*$"
- 不匹配,因为搜索字符串未被解释为正则表达式。
- echo ID: abc|findstr "ID: *[0-9]*$"
- 尽管 echo 的输出未能与完整的正则表达式匹配,但仍然匹配:搜索被解释为搜索与“ID:”或“*[0-9]*$”匹配的行。
- echo ID: 12|findstr /r /c:"ID: *[0-9]*$"
- 输出 File.txt 中所有与包含空格的单个正则表达式匹配的行。使用 /c 可以防止空格被视为逻辑或。使用 /r 会启用正则表达式处理,该处理默认情况下会被 /c 禁用。要测试这一点,请尝试以下操作
- findstr /ric:"id: *[0-9]*" File.txt
- 执行与上一个示例相同的操作,但以不区分大小写的方式。
- 虽然 findstr 允许在单个“/”后面累积这种开关,但这并不是所有命令都支持的。例如,“dir /bs”不起作用,而“dir /b /s”起作用。
- 要测试这一点,请尝试以下操作
- echo ID: 12|findstr /ric:"id: *[0-9]*$"
- echo ID: ab|findstr /ric:"id: *[0-9]*$"
- findstr /msric:"id: *[0-9]*" *.txt
- 类似上面,但递归搜索所有文件(/s),只显示匹配的文件,而不是匹配的行(/m)。
- echo hel lo | findstr /c:"hel lo" /c:world
- /c 开关可以多次使用以创建逻辑或。
- echo \hello\ | findstr "\hello\"
- 不匹配。引号和其他多个字符之前的反斜杠充当转义符;因此,\" 匹配 "。
- echo \hello\ | findstr "\\hello\\"
- 匹配。传递给 findstr 的双反斜杠代表单个反斜杠。
- echo \hello\ | findstr \hello\
- 匹配。传递给 findstr 的单个反斜杠都不后跟反斜杠用作转义符的字符。
- echo ^"hey | findstr \^"hey | more
- 要搜索引号(双引号),需要对其进行两次转义:一次用于使用插入符号 (^) 的 shell,一次用于使用反斜杠 (\) 的 findstr。
- echo ^"hey | findstr ^"\^"hey there^" | more
- 要搜索引号并将搜索词也括在引号中,需要使用插入符号 (^) 为 shell 转义封闭引号。
- echo //comment line | findstr \//
- 如果正斜杠 (/) 是搜索词中的第一个字符,则需要使用反斜杠 (\) 对其进行转义。即使搜索词括在引号中,也需要转义。
- findstr /f:FileList.txt def.*()
- 在 FileList.txt 中指定的文件中搜索,每行一个文件。FileList.txt 中的文件名可以包含空格,并且不需要用引号括起来才能正常工作。
- findstr /g:SearchTermsFile.txt *.txt
- 搜索 SearchTermsFile.txt 中找到的搜索词,每行一个搜索词。空格不用于分隔两个搜索词;相反,每一行都是一个完整的搜索词。如果至少有一个搜索词匹配,则匹配该行。如果第一个搜索词看起来像正则表达式,则搜索将是正则表达式搜索,但如果它看起来像普通搜索词,则整个搜索将是普通搜索,即使第二个或之后的搜索词看起来像正则表达式。
- findstr /xlg:File1.txt File2.txt
- 输出集合交集:两个文件中都存在的行。
- findstr /xlvg:File2.txt File1.txt
- 输出集合差:File1.txt - File2.txt。
- findstr /m Microsoft C:\Windows\system32\*.com
- 不仅适用于文本文件,也适用于二进制文件。
"findstr" 正则表达式的限制,与 "grep" 相比
- 不支持组 -- "\(", "\)"。
- 不支持贪婪迭代器 -- "*?"。
- 不支持“前一个的零个或一个” -- "?"。
- 以及更多。
其他限制:正如在Windows FINDSTR 命令的未公开功能和限制是什么?中记录的那样,存在各种限制和奇怪的行为。
错误
- echo bb|findstr "bb baaaa"
- 在多个 Windows 版本中找不到任何内容,但它应该能找到。
还可以考虑键入“findstr /?”。
链接
- ss64.com 上的 findstr
- Microsoft 上的 findstr
- Windows FINDSTR 命令的未公开功能和限制是什么? 在 StackOverflow 上
根据修改日期和文件名模式查找文件,并对每个找到的文件执行命令。非常有限,特别是与其他操作系统的 find 命令相比。自 Windows Vista 起可用。有关更多信息,请键入“forfiles /?”。
示例
- forfiles /s /d 06/10/2015 /c "cmd /c echo @fdate @path"
- 对于当前文件夹及其子文件夹中 2015 年 6 月 10 日或之后修改的每个文件,输出文件修改日期和完整文件路径。/d 后面的日期格式是特定于区域设置的。因此,允许查找最近修改的文件。关键词:最近更改的文件。
- forfiles /m *.txt /s /d 06/10/2015 /c "cmd /c echo @fdate @path"
- 如上所述,但仅适用于以 .txt 结尾的文件。
链接
forfiles /?
格式化磁盘以使用 Windows 支持的文件系统(如 FAT、FAT32 或 NTFS),从而覆盖磁盘上的先前内容。谨慎使用。
链接
一个强大的工具,执行与 FAT 和 NTFS 文件系统相关的操作,理想情况下仅供拥有广泛操作系统知识的资深用户使用。
链接
输出用户或计算机的组策略设置等。
链接
在图形模式下启用扩展字符集的显示。有关更多信息,请键入“graftabl /?”。
链接
显示命令帮助。
示例
- help
- 显示 Windows 提供的命令列表。
- help copy
- 显示 COPY 命令的帮助,也可以通过键入“copy /?”来获得。
链接
(XP 中没有)显示或更改文件或文件夹的自由访问控制列表 (DACL)。另请参见CACLS。有关更多信息,请键入“icacls /?”。
链接
输出 Windows IP 配置。按连接显示配置以及该连接的名称(即以太网适配器本地连接)在其下方显示与该连接相关的特定信息,例如 DNS 后缀和 IP 地址以及子网掩码。
链接
添加、设置或删除磁盘标签。
链接
将文件放入压缩的 .cab 压缩包文件中。另请参见#EXPAND。
链接
一个多用途命令,用于显示设备状态、配置端口和设备等。
示例
- mode
- 输出所有设备(如 com3 和 con)的状态和配置。
- mode con
- 输出 con 设备(命令解释器正在运行的控制台)的状态和配置。
- mode con cols=120 lines=20
- 设置当前控制台的列数和行数,导致窗口大小调整并清除屏幕。该设置不影响新的控制台实例。关键词:宽屏、宽窗口、屏幕尺寸、窗口尺寸、调整屏幕大小、调整窗口大小。
- mode 120, 20
- 如上所述:设置列数 (120) 和行数 (20),导致窗口大小调整并清除屏幕。
- mode con cols=120
- 设置当前控制台的列数,导致窗口大小调整并清除屏幕。它似乎也更改了可见行数,但控制台缓冲区的总行数似乎没有改变。
- mode 120
- 如上所述:设置列数。
- mode con cp
- 输出控制台的当前代码页。
- mode con cp select=850
- 设置控制台的当前代码页。有关代码页列表,请参见下面链接的 Microsoft 文档。
- mode con rate=31 delay=1
- 设置按住键时字符重复输入的速率和延迟,控制台。速率越低,每秒的重复次数越少。
链接
每次显示一个屏幕的文件或多个文件的内容。当重定向到文件时,也会执行一些转换,具体取决于使用的开关。
示例
- more Test.txt
- more *.txt
- grep -i sought.*string Source.txt | more /p >Out.txt
- 获取一个非 Windows grep 命令的输出,该命令生成的换行符仅由 LF 字符组成,不包含 CR 字符,将 LF 换行符转换为 CR-LF 换行符。CR-LF 换行符也称为 DOS 换行符、Windows 换行符、DOS 换行符、Windows 换行符和 CR/LF 行尾,与某些其他操作系统使用的 LF 换行符相反。
- 在某些设置中,如果输入同时包含 LF 换行符和制表符,则似乎会输出乱码。
- 在某些设置中,对于转换,/p 可能不需要。因此,“more”即使没有 /p 也会转换换行符。
- more /t4 Source.txt >Target.txt
- 将制表符转换为 4 个空格。
- 在某些设置中,即使没有 /t 开关,制表符转换也会自动进行。如果是这样,默认情况下为 8 个空格。
开关 /e
- Windows XP 和 Windows Vista 中“more”的在线文档中未提及该开关。
- 至少在 Windows XP 和 Windows Vista 中,“more /?”中提到了开关 /e。
- 根据“more /?”,该开关应该启用“more /?”帮助末尾列出的扩展功能,例如在按下“=”时显示当前行。但是,在 Windows XP 和 Windows Vista 中,即使没有 /e,似乎也默认启用了该功能。
- 假设:在 Windows XP 和 Windows Vista 中,/e 没有任何作用;它出于兼容性原因而存在。
链接
- more at ss64.com
- more at Microsoft,Windows XP
- more at Microsoft,Windows Server 2008,Windows Vista
提供各种网络服务,具体取决于使用的命令。每个命令可用的变体
- net accounts
- net computer
- net config
- net continue
- net file
- net group
- net help
- net helpmsg
- net localgroup
- net name
- net pause
- net print
- net send
- net session
- net share
- net start
- net statistics
- net stop
- net time
- net use
- net user
- net view
链接
执行与打开文件相关的操作,尤其是通过网络由其他用户打开的文件。这些操作包括查询、显示和断开连接。有关更多信息,请键入“openfiles /?”。
链接
语法
- PING /?
- PING address
- PING hostname
通过网络向指定的地址(或指定主机名通过名称查找映射到的第一个 IP 地址)发送ICMP/IP“回显”数据包,并打印收到的所有响应。
示例
- ping en.wikibooks.org
- ping 91.198.174.192
- ping https://wikibooks.cn/
- 不起作用。
链接
从有缺陷磁盘上的损坏文件中恢复尽可能多的信息。
链接
查询或修改 Windows 注册表。
第一个参数是以下命令之一:query、add、delete、copy、save、load、unload、restore、compare、export、import 和标志。要详细了解某个命令,请在其后加上 /?,例如 reg query /?。
链接
用源文件夹中同名文件替换目标文件夹中的文件。
链接
(XP 中没有)复制文件和文件夹。另请参见XCOPY和COPY。
示例
- robocopy /s C:\Windows\system C:\Windows-2\system *.dll
- 将以 .dll 结尾的所有文件从一个目录复制到另一个目录,复制嵌套的目录结构。
链接
运行 DLL 中提供的函数。可用的 DLL 及其函数在不同的 Windows 版本中有所不同。
示例
- rundll32 sysdm.cpl,EditEnvironmentVariables
- 在某些 Windows 版本中,打开编辑环境变量的对话框。
链接
- rundll32 at ss64.com
- 在Microsoft
- rundll at robvanderwoude.com
- dx21.com - 列出 rundll32 示例
控制 Windows 服务,支持启动、停止、查询等。Windows 服务类似于进程。Windows 服务要么在其自己的进程中托管,要么托管在 svchost.exe 进程的实例中,通常在一个实例中有多个服务。可以使用 Sysinternals 的免费下载的 Process Explorer 找到特定服务的处理器时间使用情况,方法是转到服务的属性,然后转到“线程”选项卡。另一个能够控制服务的命令是NET。TASKLIST可以使用 /svc 开关列出托管的服务。
示例
- sc start wuauserv
- 启动 wuauserv 服务。
- sc stop wuauserv
- sc query wuauserv
- sc query
- 输出有关所有服务的信息。
- sc config SysMain start= disabled
- 确保在启动后禁用 SysMain 服务。SysMain 是 SuperFetch 服务,通过尝试猜测哪些程序将在加载到 RAM 中以防使用,并加载它们,从而导致重复的硬盘活动。请注意,在 = 之前必须没有空格,在 = 之后必须有空格。
链接
计划在特定时间运行程序,比AT更强大。
链接
类似于SET,但影响整个计算机而不是当前控制台或进程。Windows XP 中不可用;Windows Vista 及更高版本中可用。
链接
- setx at ss64.com
- setx at Microsoft,Windows Server 2008,Windows Vista
关闭计算机或注销当前用户。
示例
- shutdown /s
- 关闭计算机。
- shutdown /s /t 0
- 立即关闭计算机。
- shutdown /l
- 注销当前用户。
链接
按字母顺序排序,从 A 到 Z 或 Z 到 A,不区分大小写。无法按数字排序:如果输入每行包含一个整数,“12”在“9”之前。
示例
- sort File.txt
- 输出 File.txt 的排序内容。
- sort /r File.txt
- 按反向顺序排序,从 Z 到 A。
- dir /b | sort
链接
将驱动器号分配给本地文件夹,输出当前分配或删除分配。
示例
- subst p: .
- 将 p: 分配给当前文件夹。
- subst
- 输出以前使用 subst 创建的所有分配。
- subst /d p
- 删除 p: 分配。
链接
显示计算机及其操作系统的配置。
链接
结束一个或多个任务。
示例
- taskkill /im AcroRd32.exe
- 结束所有名为“AcroRd32.exe”的进程;从而结束所有打开的 Acrobat Reader 实例。可以使用 tasklist 找到名称。
- taskkill /f /im AcroRd32.exe
- 与上面相同,但强制执行。成功结束了一些没有 /f 则无法结束的进程。
- tasklist | find "notepad"
taskkill /PID 5792
- 结束进程 ID (PID) 为 5792 的进程;假设您已使用 tasklist 找到了 PID。
链接
列出任务,包括任务名称和进程 ID (PID)。
示例
- tasklist | sort
- tasklist | find "AcroRd"
- tasklist | find /C "chrome.exe"
- 输出名为“chrome.exe”的任务数量,属于 Google Chrome 浏览器。
- tasklist /svc | findstr svchost
- 输出在 svchost.exe 进程中托管的 Windows 服务,以及有关该进程的常规信息。
链接
等待指定秒数,显示剩余秒数,允许用户通过按任意键中断等待。也称为延迟或睡眠。在 Windows Vista 及更高版本中可用。
示例
- timeout /t 5
- 等待五秒钟,允许用户通过按任意键取消等待。
- timeout /t 5 /nobreak
- 等待五秒钟,忽略除 Control + C 之外的用户输入。
- timeout /t 5 /nobreak >nul
- 与上面相同,但没有输出。
Windows XP 中的解决方法
- ping -n 6 127.0.0.1 >nul
- 等待五秒钟;-n 后面的数字是等待的秒数加 1。
Windows XP 中基于 Perl 的解决方法,需要安装 Perl
- perl -e "sleep 5"
- 等待 5 秒。
链接
- timeout 在 ss64.com 上
- timeout 在 Microsoft 上
- 如何在批处理脚本中等待? 在 stackoverflow.com 上
- 在批处理文件中睡眠 在 stackoverflow.com 上
将当前目录的所有子目录的树输出到任何级别的递归或深度。如果与 /F 开关一起使用,则不仅输出子目录,还输出文件。
示例
- tree
- tree /f
- 除了目录之外,还包括列表中的文件。
- tree /f /a
- 与上面相同,但使用 7 位 ASCII 字符(包括“+”、“-”和“\”)绘制树。
使用 8 位 ASCII 字符的树片段
├───winevt │ ├───Logs │ └───TraceFormat ├───winrm
使用 7 位 ASCII 字符的树片段
+---winevt | +---Logs | \---TraceFormat +---winrm
链接
输出文件或文件名模式的一个或多个位置,其中文件或模式不需要声明扩展名,如果它在 PATHEXT 中列出,例如 .exe。默认情况下在当前目录和 PATH 中搜索。执行一些其他操作系统的“which”命令的工作,但更灵活。
在 Windows 2003、Windows Vista、Windows 7 及更高版本中可用;在 Windows XP 中不可用。下面示例中提供了可在 Windows XP 中使用的替代方案。
找不到内部命令,因为没有与之匹配的 .exe 文件。
示例
- where find
- 输出 find 命令的位置,可能是“C:\Windows\System32\find.exe”。只要 .exe 扩展名在 PATHEXT 中列出,就不需要指定它,默认情况下它是列出的。
- 如果路径中有多个 find 命令,则输出两个命令的路径。在某些情况下,它可能会输出以下内容
C:\Windows\System32\find.exe
C:\Program Files\GnuWin32\bin\find.exe
- for %i in (find.exe) do @echo %~$PATH:i
- 在 Windows XP 上输出“find.exe”的位置。与 where 命令不同,名称必须包含“.exe”。
- where /r . Tasks*
- 从当前文件夹递归搜索名称与“Task*”匹配的文件。类似于“dir /b /s Tasks*”。/r 开关禁用在 PATH 中的文件夹中搜索。
- where *.bat
- 输出当前目录和 PATH 中的目录中的所有 .bat 文件。因此,输出所有无需输入完整路径即可运行的 .bat 文件。
- where ls*.bat
- 与上面相同,也限制 .bat 文件名称的开头。
- where ls*
- 与上面相同,但对扩展名没有限制。如果在当前目录或路径中,则查找 lsdisks.bat、lsmice.pl 和 lsmnts.py。
- where *.exe *.com | more
- 输出路径和当前文件夹中无数的 .exe 和 .com 文件,包括 C:\Windows\System32 中的文件。
- where $path:*.bat
- 输出路径中的 .bat 文件,但不输出当前文件夹中的文件,除非当前文件夹在 PATH 中。可以使用包含目录列表的其他环境变量代替 path。
- where $windir:*.exe
- 输出在 WINDIR 环境变量中声明的文件夹中找到的 .exe 文件。
- where $path:*.bat $windir:*.exe
- 可以进行组合。输出与两个查询中的任一个匹配的所有文件。
- where /q *.bat && echo Found
- 抑制标准输出和错误输出,但设置错误级别,以便对其进行测试。无论是否使用 /q,都会设置错误级别。
链接
启动 Windows Management Instrumentation 命令行 (WMIC),或者在给出参数的情况下,将参数作为命令传递给 WMIC。Windows XP Home 中没有。有关更多信息,请键入“wmic /?”。
示例
- wmic logicaldisk get caption,description
- 列出在驱动器号下可访问的驱动器(磁盘),无论是本地硬盘驱动器、CD-ROM 驱动器、可移动闪存驱动器、网络驱动器还是使用 #SUBST 创建的驱动器。
- wmic logicaldisk get /format:list
- 输出“logicaldisk”对象的全部属性,每个属性占据一行。
- wmic logicaldisk get /format:csv
- wmic
Control + C- 进入 wmic 然后中断它。一个副作用是控制台缓冲区变得非常宽,并且因此屏幕可以通过鼠标水平调整大小。这是 wmic 设置控制台列数较高的结果,您可以使用mode con验证。您可以通过键入mode 1500获得类似的结果。另请参见 #MODE。
- wmic datafile where name="C:\\Windows\\System32\\cmd.exe" get Version /value
- 输出 cmd.exe 的版本,应该接近 Windows 版本。
- wmic os get TotalVisibleMemorySize
- 输出总物理内存大小。
- wmic os get TotalVirtualMemorySize
- 输出总虚拟内存大小。
- wmic os get /format:list
- 输出“os”对象的全部属性,每个属性占据一行。
链接
以比 COPY 更高级的方式复制文件和目录,在 Windows Vista 及更高版本中已弃用,取而代之的是 ROBOCOPY。键入 xcopy /? 以了解更多信息,包括无数选项。
示例
- xcopy C:\Windows\system
- 复制所有文件,但不复制嵌套文件夹中的文件,从源文件夹(“C:\Windows\system”)复制到当前文件夹。
- xcopy /s /i C:\Windows\system C:\Windows-2\system
- 将所有文件和文件夹复制到任何嵌套深度(通过“/s”),从源文件夹(“C:\Windows\system”)复制到“C:\Windows-2\system”,如果“Windows-2\system”不存在则创建它(通过“/i”)。
- xcopy /s /i /d:09-01-2014 C:\Windows\system C:\Windows-2\system
- 与上面相同,但仅复制 2014 年 9 月 1 日或之后更改的文件。请注意,即使您使用的是非美国 Windows 区域设置,也使用了月优先约定。
- xcopy /L /s /i /d:09-01-2014 C:\Windows\system C:\Windows-2\system
- 与上面示例相同,但通过 /L(仅列出、仅输出、仅显示)以测试模式运行。因此,它不会执行任何实际复制操作,而只是列出将要复制的内容。
- xcopy /s /i C:\Windows\system\*.dll C:\Windows-2\system
- 与上面示例之一相同,但仅复制以 .dll 结尾的文件,包括嵌套文件夹中的文件。
链接
- PowerShell -- 用于编写 Windows 操作系统脚本的现代技术
- VBScript 编程 -- 一种语法类似于 Visual Basic 的传统 Windows 脚本技术
- ss64.com 上的 Windows CMD 命令 -- 根据知识共享署名-非商业性使用-相同方式共享 2.0 英国:英格兰及威尔士[1]许可,因此与 Wikibooks 使用的 CC-BY-SA 不兼容
- microsoft.com 上的 Windows XP - 命令行参考 A-Z
- microsoft.com 上的 Windows Server 2008R2 - 命令行参考
- microsoft.com 上的 Windows Server 2012R2 - 命令行参考
- microsoft.com 上的 Windows Server 2016 - Windows 命令
- FreeDOS HTML 帮助 在 fdos.org -- FreeDOS 命令的超文本帮助系统,编写于 2003/2004 年,根据 GNU 自由文档许可证 提供
- 批处理文件分类,rosettacode.org
- Cmd.exe,wikipedia.org
- 批处理文件,wikipedia.org