批处理基础
- 不要折腾 Windows CMD 的 Batch file 了,系统切换语言后,字符编码是最大的问题,并且,功能过于基础,组装成应用比较麻烦;
- 建议安装 Git 客户端,写基于 Bash 的脚本,适用性更强 (对工作帮助更大);或者 PowerShell。
前话
批处理,维基上是这么定义的:“在 DOS、OS/2、微软视窗系统中,是一种用来当成脚本语言运作程序的文件。它本身是文本文件,其中包含了一系列让具备命令行界面的解释器读取并运行的指令。它相当于是类 Unix 系统下的 Shell script。文件扩展名为 .bat
或 .cmd
,Shell 程序逐行运行命令”。
就是在命令行界面 (CLI) 执行指令,为的就是一个快,省事,偷懒,不依赖其它软件。
Windows 10, 8, 7, Vista 和 XP 中的命令称为‘CMD 命令’或‘命令提示符命令’,而 Windows 98/95 和 MS-DOS 中的命令则称为‘DOS 命令’。
本篇讲基础,后面的讲实际实用。
基础部分扫一两遍,旨在认识,不在熟悉。
.
当前目录..
上一层目录\
根目录
- 文件及目录路径:使用反斜杠
\
,不使用正斜杠/
- 文件及目录路径:存在空格,使用双引号包裹路径
- 不可用于文件目录名的字符:
\ / : * ? " < > |
- 需双引号包裹的字符:
( ) [ ] { } ^ = ; ! ' + , ` ~ & 空格
- 转义字符
^
- 需要转义的字符:
^
、<
、>
、|
、&
%%
自己可以转义自己rem
(回显)和::
(不回显)注释语句@
隐藏命令的回显echo
不显示命令本身,只显示执行后结果pause >nul
暂停,隐藏 pause 显示的信息
常用 DOS 命令
command /?
查看 command 命令帮助说明cd/chdir /d [drive:][path]
md/mkdir [drive:][path]
rd/rmdir [/s] [/q] [drive:]path
删除子目录树/安静模式copy /?
ren/rename /?
move /?
del/erase /?
attrib /?
tree /?
dir /?
find /?
findstr /?
sort /?
xcopy /?
type /?
more
逐屏显示输出set
显示、设置或删除 cmd.exe 环境变量。/p
用户输入,/a
数学运算
建议 CMD cd
到桌面以 help >> cli_help.txt
、cd /? >> cd_help.txt
这类方式深入查阅相关命令说明。
if/else
语句
if exist
判断驱动器、文件或文件夹是否存在if "字符串1"=="字符串2"
判断某两个字符串是否相等if defined str
判断某个变量是否已经被赋值if 数值1 equ 数值2
判断某两个数值是否相等+ `equ`, equal
+ `gtr`, greater than
+ `geq`, greater than or equal
+ `lss`, less than
+ `leq`, less than or equal
+ `neq`, no equal
for
语句
for %variable in(set) do command [command-parameters]
遍历目录(directory)
for /D %variable in(set) DO command [command-parameters]
如果集中包含通配符,则指定与目录名匹配,而不与文件名匹配。递归遍历
for /R [[drive:]path] %variable IN (set) DO command [command-parameters]
检查以 [drive:]path 为根的目录树,指向每个目录中的 FOR 语句。如果在 /R 后没有指定目录规范,则使用当前目录。如果集仅为一个单点(.)字符,则枚举该目录树。计数循环
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.for /F
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]
- "options"(delims、tokens、skip、eol、userbackq、变量延迟)
解析文本,读取字符串,
eol=str - 忽略以指定字符打头的行(默认忽略以分号打头的行的功能,因为以分号打头的行在很多语言中都是作为注释语句)
skip=n - 跳过无关内容,直奔主题
delims=符号列表 - 切分字符串的利器,默认以空格和 Tab 作分割符
tokens=x,y,m-n - 定点提取
%~I - 删除任何引号("),扩展 %I(形式变量)
%~fI - 将 %I 扩展到一个完全合格的路径名
%~dI - 仅将 %I 扩展到一个驱动器号
%~pI - 仅将 %I 扩展到一个路径
%~nI - 仅将 %I 扩展到一个文件名
%~xI - 仅将 %I 扩展到一个文件扩展名
%~sI - 扩展的路径只含有短名
%~aI - 将 %I 扩展到文件的文件属性
%~tI - 将 %I 扩展到文件的日期/时间
%~zI - 将 %I 扩展到文件的大小
%~$PATH:I - 查找列在路径环境变量的目录,并将 %I 扩展
到找到的第一个完全合格的名称。如果环境变量名
未被定义,或者没有找到文件,此组合键会扩展到
空字符串
可以组合修饰符来得到多重结果:
%~dpI - 仅将 %I 扩展到一个驱动器号和路径
%~nxI - 仅将 %I 扩展到一个文件名和扩展名
%~fsI - 仅将 %I 扩展到一个带有短名的完整路径名
%~dp$PATH:I - 搜索列在路径环境变量的目录,并将 %I 扩展
到找到的第一个驱动器号和路径。
%~ftzaI - 将 %I 扩展到类似输出线路的 DIR
usebackq
,增强型参数
原来的 for 语句中第一个括号内的写法要做如下变动:
- 如果第一个括号里的对象是一条命令语句,原来的单引号
'
要改为后引号`
; - 如果第一个括号里的对象是字符串,原来的双引号
"
要改为单引号'
; - 如果第一个括号里的对象是文件名,要用双引号
"
括起来。
for
语句不能直接读取 Unicode 编码的文本,需要借助 type
或 more
预处理机制
逐条,命令关键字,运算符,开关、参数,变量引用…
所有的变量引用都已被替换成字符串常量,变量值在复合语句内部被改变,不会影响到语句内部的其他任何地方。
延迟变量的扩展行为
在适当位置使用 SetLocal EnableDelayedExpansion
语句,把原本使用百分号对闭合的变量引用改为使用感叹号对来闭合
@echo off
SetLocal EnableDelayedExpansion
set num=0&&echo !num!
pause
在适当的位置使用 call
语句,把变量引用的单层百分号对改为双层百分号对
@echo off
set num=0&&call echo %%num%%
pause
为什么要使用变量延迟?因为要让复合语句内部的变量实时感知到变量值的变化。
复合语句有:for
语句、if
else
语句、用连接符 &
、||
和 &&
连接的语句、用管道符号 |
连接的语句,以及用 括号
括起来的、由多条语句组合而成的语句块。
特殊字符
@
,隐藏命令的回显~
- 在
for
中表示使用增强的变量扩展 - 在
set
中表示使用扩展环境变量指定位置的字符串 - 在
set /a
中表示按位取反
- 在
^
- 取消特殊字符作用,字符转义;
echo
输出时,可以将^
后的下一行的字符串拼接在当前行后输出- 在
set /a
中是按位异; - 在
findstr /r
的[]
中表示不匹配指定的字符集
&
- 命令连接字符,顺序执行多条命令,不论命令是否执行成功
- 在
set /a
中是按位与
|
- 管道符,就是将上一个命令的输出,作为下一个命令的输入;传输执行结果
- 在帮助文档中表示其前后两个开关、选项或参数是二选一的
- 在
set /a
中是按位或
&&
,连接两个命令,&&
前命令执行成功,则执行&&
后命令;传输执行状态||
,连接两个命令,||
前命令执行失败,则执行||
后命令。传输执行状态()
,命令包含或者是具有优先权的界定符[]
- 在帮助文档表示其中的开关、选项或参数是可选的
- 在
findstr /r
中表示按其中指定的字符集匹配
+
copy
将很多个文件合并为一个文件- 在
set /a
中是加法
-
- 范围表示符,如日期的查找,
for
命令里的tokens
操作中就可以用到这个字符 - 在
findstr /r
中连接两个字符表示匹配范围; -
跟在命令的/
后表示取反向的开关。
- 范围表示符,如日期的查找,
*
- 通配符,代表任意个任意字符
- 在
set /a
中是乘法 - 在
findstr /r
中表示将前一个字符多次匹配 findstr
正则表达式中,.
代表任意字符,*
代表0个或多个,.*
表示0个或多个任意字符
/
- 表示其后的字符(串)是命令的功能开关(选项)
- 在
set /a
中表示除法
=
- 赋值符号,用于变量的赋值
- 在
set /a
中表示算术运算
:
,标签定位符,可以接受goto
命令所指向的标签" "
- 界定符,带有空格的路径,一些命令也需要
" "
符号 - 在
for /f
中将表示它们包含的内容当作字符串分析 - 在
for /f "usebackq"
表示它们包含的内容当作文件路径并分析其文件的内容 - 在其它情况下表示其中的内容是一个完整的字符串,其中的
>
、>>
、<
、&
、|
、空格等不再转义
- 界定符,带有空格的路径,一些命令也需要
>
- 命令重定向符,覆盖方式重定向提示信息
- 在
findstr /r
中表示匹配单词的右边界,需要配合转义字符\
使用
>>
,命令重定向符,追加方式重定向提示信息<
- 将其后面的文件的内容作为其前面命令的输入
- 在
findstr /r
中表示匹配单词的左边界,需要配合转义字符\
使用
\
- 当前路径的根目录
- 在
findstr /r
中表示正则转义字符
' '
- 在
for /f
中表示将它们包含的内容当作命令行执行并分析其输出 - 在
for /f "usebackq"
中表示将它们包含的字符串当作字符串分析
- 在
.
.
当前目录,..
上一层目录- 在路径中的文件名中出现时:最后的一个
.
表示主文件名与扩展文件名的分隔
$
,在findstr
命令里面表示一行的结束\`\`
,在 `for /f` 中表示它们所包含的内容当作命令行执行并分析它的输出?
- 在
findstr /r
中表示在此位置匹配一个任意字符 ?
在路径中表示在此位置通配任意一个字符- 紧跟在
/
后表示获取命令的帮助文档
- 在
!
- 当启用变量延迟时,使用
! !
将变量名扩起来表示对变量值的引用 - 在
set /a
中表示逻辑非,比如set /a a=!0
,这时 a 就表示逻辑1
- 当启用变量延迟时,使用
% %
,非延迟环境变量引用符号,
,相当于空格;
,命令相同的时候,可以将不同的目标用;
隔离开来,但执行效果不变。如执行过程中发生错误则只返回错误报告但程序还是会继续执行。
"\>"
、"\<"
、"\@"
、"\|"
不能实现自己想要的功能,将特殊字符替换成 ASCII 表中的十进制数,然后再把 ASCII 的10进制数换算成 ASCII 字符处理。
变量
set varName=varValue
set /p var=请输入变量的值:
,等待用户输入到 var
变量中
set /p= hello world! <nul
set /a
运算表达式
内部处理变量
if defined
和 set /a
因为都是在内部处理变量,而不是在预处理过程中处理,也就是说不需要使用变量扩展标记,所以天然具有变量延迟的特性;
至于逗号表达式,这是 set /a
才能处理的特性;
cmd 的预处理过程,是把两个表达式理解为一句,而不是一个语句块,所以自然不可能延迟扩展变量。
Windows Command Line |Shell List and Reference
更新日志:
- 2017-05-15