学习 Bat 脚本

bat 语法

符号

| 符号 | 描述 |
| —- | ———————————————————— |
| @ | 隐藏命令回显 |
| ~ | for 中表示使用增强的变量扩展
在 set 中表示使用扩展变量指定位置字符串
在 set /a 中表示按位取反 |
| % | 两个%%包裹的字符串表示环境变量
%0 ~ %9 表示引用命令行参数
在 for 中表示循环变量
%% 表示在执行时变为一个 % |
| ^ | 取消转义字符
在 findstr /r 的 [] 表示不匹配的指定字符串 |
| & | 命令连接符(命令1 & 命令2)
在 set /a 中表示按位与 |
| * | 通配符
在 set /a 中为乘法
在 findstr /r 中表示前个字符多个匹配 |
| () | 括号中可多行命令
在 for 和 if 中常用 |
| - | 范围表示符
在 for 中的 tokens 可用到
跟在某些命令行 / 后表示取反向 |
| + | 用在 copy 中,将多个文件合成一个
在 set /a 中是加法 |
| \| | 管道符
将上一命令输出作为下一命令输入
在 set /a 中是按位或 |
| : | 标签定位符
可接受 goto 命令所指向的标签 (goto End) |
| " " | 界定符
在用带空格路径时将路径扩起
在 for /f 中表示将包含内容作为字符串分析
在 for /f “usebackq” |
| / | 其后的字符是命令的功能开关 |
| > | 定向符 将输出内容重定向到指定(文本) |
| » | 定向符 追加模式 |
| < | 输入定向符 从指定(文本)获取内容 |
| = | 赋值符号 |
| \ | 一般代表路径,findstr /r 中表示转义字符 |
| '' | 在for/f中表示将它们包含的内容当作命令行执行并分析其输出
在for/f “usebackq"中表示将它们包含的字符串当作字符串分析 |
| . | 一般表示路径 ./ 当前, ../ 上级, 文件名中的最后一个表示文件名和扩展名的分割 |
| && | 连接符 前面的执行完毕再执行后面的 |
| \|\| | 连接符 前面的没执行成功,就执行后面的 |
| $ | findstr 中表示一行的结束 |
| `` | for /f 中表示将内容作为命令并分析输出 |
| [] | 在帮助文档中表示内容可选,findstr /r 中表示指定字符集匹配 |
| ? | 通配符 单个字符 |
| ! | 变量延迟启用是,以!!将变量名括起标识对变量值的引用 |

命令

echo 输出内容

echo [on | off] [message]
  • on | off 指定是否允许命令回显
  • message 为输出内容
:关闭回显
@echo off
:打印123
echo 123

pause 暂停

需要按任意键继续。

pause

注释

单行注释

rem [message]
  • message 指定屏蔽的命令或注释
::注释内容
:注释内容 不能包含 goto 可指向的标签
goto 标签 注释内容(用作 goto 说明)
:标签 注释内容

多行注释

goto start
可以是多行文本或命令
可以包含重定向符号或其他字符串
只要不包含 :start 就都是注释
wwaaw
awawa
:start

重定向符 > »

用于将命令输出写到指定位置。

如 写入文件、nul(空设备)。

>

将输出写入指定文件,nul(空设备,用于放弃输出)等。

会覆盖文件已有内容。

»

与 > 符号类似,不过是追加而非覆盖。

屏蔽错误

:ipcnogif 是一个错误命令 将会报错
ipcnogif > nul 2 > nul
:会隐藏此命令报错
:> nul 等效于 1 > nul
:> nul 前的 1 表示输出流 2 表示错误流(1可省略)

文件参数

批处理中可引用参数为 %0 ~ %9。

%0 表示批处理文件本身。

%1 ~ %9 则是批处理参数。

也称形参。

超过 9 个参数时

使用 shift 命令进行偏移。

如果参数未传入,则变量为空。

@echo off
echo %1 %9
shif /0
:偏移0
echo %1 %2 ...
shif /1
:偏移1

errorlevel 错误等级

常用于判断上个命令的执行情况。

一般上条命令执行结果只有 1(失败)或 0(成功)。

实际上 errorlevel 值范围在 0~255 之间。

比如 xcopy 的 errorlevel 就有五个值。

  • 0 复制文件成功。
  • 1 未找到复制文件。
  • 2 用户通过 ctrl + c 终止操作。
  • 4 初始化错误。
  • 5 磁盘写入错误。

比较

| 参数 | 描述 | 例子 |
| —- | ———– | ———- |
| EQU | 等于 = | if 1 EQU 1 |
| NEQ | 不等于 != | if 1 NEQ 1 |
| LSS | 小于 < | if 1 LSS 1 |
| LEQ | 小于等于 <= | if 1 LEQ 1 |
| GTR | 大于 > | if 1 GTR 1 |
| GEQ | 大于等于 >= | if 1 GEQ 1 |

set

set [variable=[string]]
  • variable 指定变量名 不允许包含 等号(=)
  • string 指定派给变量的值

如果需要显示当前环境变量,可直接 set Variable 会直接输出变量值。

启用变量扩展后,set p 会查找所有以 p 开头的变量。

如果未找到,则 errorlevel 变更为 1。

扩展命令

set /a 数字表达式
set /p 提示字符串
  • /a

| 操作符 | 描述 |
| ———————————- | ———— |
| () | 分组 |
| ! ~ - | 一元运算符 |
| * / % | 算数运算符 |
| « » | 逻辑移位 |
| | 按位“与” |
| | 按位“异” |
| \| | 按位“或” |
| = *= /= %= += -= &=
= \|= «= »= | 赋值 |
| , | 表达式分隔符 |

  • /p

将变量设置为用户输入,会提示预设提示字符串。

环境变量替换

%path:str1=str2%
  • path 变量名称
  • str1 替换的原字符串
  • str2 替换后的字符串

子字符串

%path:~10,5%

以上会截取该变量偏移量从十个开始的五个字符。

如果两个数字(偏移量和长度)都是负数,使用的数字则是环境变量数值长度加上指定的偏移量或长度。

延迟环境变量

使用 cmd /V:on 启用。

set var=1
if %var% == 1 (
    set var=2
    :将永远不会执行
    :因为读到第一个 if 时,两个 %var% 会被代替
    if %var% == 2 echo 2
)

启用后将允许使用 ! 符号在执行时扩展变量。

set var=1
if %var% == 1 (
    set var=2
    :将会执行
    if !var! == 2 echo 2
)

如果命令扩展被启用,有几个动态环境变量可以被扩展,但不会出现在 SET 显示的变量列表中。每次变量数值被扩展时,这些变量数值都会被动态计算。如果用户用这些名称中任何一个明确定义变量,那个定义会替代下面描述的动态定义:

  • %CD% - 扩展到当前目录字符串。
  • %DATE% - 用跟 DATE 命令同样的格式扩展到当前日期。
  • %TIME% - 用跟 TIME 命令同样的格式扩展到当前时间。
  • %RANDOM% - 扩展到 0 和 32767 之间的任意十进制数字。
  • %ERRORLEVEL% - 扩展到当前 ERRORLEVEL 数值。
  • %CMDEXTVERSION% - 扩展到当前命令处理器扩展版本号。
  • %CMDCMDLINE% - 扩展到调用命令处理器的原始命令行。
  • %HIGHESTNUMANODENUMBER% - 扩展到此计算机上的最高 NUMA 节点号。

setlocal 和 endlocal

创建一个作用域。

所有的环境改动只限于此批处理文件。

无论在 setlocal 命令之前它们的设置是什么,这些修改会一直保留到匹配的 endlocal 命令。

接受参数:

  • enableextensions / disableextensions 启用或禁用命令处理器扩展。这些参数比 cmd /e:on 或 /e:off 开关有优先权。请参阅 cmd /? 获取详细信息。
  • enabledelayedexpansion / disabledelayedexpansion 启用或禁用延缓环境变量扩展。这些参数比 cmd /v:on 或 /v:off 开关有优先权。请参阅 cmd /? 获取详细信息。
@ECHO OFF
VERIFY OTHER 2>nul
SETLOCAL ENABLEEXTENSIONS
:在 cmd.exe 的旧版本上,setlocal 未设置 errorlevel 值。具有不正确参数的 verify 命令将 errorlevel值初始化成非零值。
IF ERRORLEVEL 1 ``echo` `Unable to ``enable` `extensions

设备

| 名称 | 描述 |
| —— | ———————- |
| con | 控制台(键盘、显示器) |
| aux | com1 - com4 所有串口 |
| prn | lpt1 - lpt3 所有并口 |
| nul | 空设备 |
| clock$ | 电子钟 |

路径

%cd%

%cd% 返回的是当前执行环境目录(如果是DOS窗口,则是DOS窗口里面的路径),并非是 bat 脚本实际所在的路径。

%~dp0

%~dp0 可以用来获取批处理文件的实际路径,与当前 DOS 环境所在的目录没有关系。其中:

  • %~dp0 的 “d” 为 Drive 的缩写,即为驱动器,磁盘。
  • %~dp0 的 “p” 为 Path 缩写,即为路径,目录。

更多选项语法:

  • ~0 删除任何引号(“),扩充 %0
  • %~d0 仅将 %0 扩充到一个驱动器号
  • %~f0 将 %0 扩充到一个完全合格的路径名(“f” 是 file,即文件)
  • %~p0 仅将 %0 扩充到一个路径
  • %~n0 仅将 %0 扩充到一个文件名(“n” 是 name 文件名)
  • %~x0 仅将 %0 扩充到一个文件扩展名
  • %~s0 扩充的路径只含有短名(“s” 为 Short,短的)
  • %~a0 将 %0 扩充到文件的文件属性(“a” 为 attribute,即属性)
  • %~t0 将 %0 扩充到文件的日期/时间(“t” time)
  • %~z0 将 %0 扩充到文件的大小(Size 大小)
  • %~$PATH:0 查找列在路径环境变量的目录,并将 %0 扩充到找到的第一个完全合格的名称。如果环境变量名未被定义,或者没有找到文件,此组合键会扩充到空字符串

可以组合修饰符来得到多重结果:

  • %~dp0 仅将 %0 扩充到一个驱动器号和路径
  • %~nx0 仅将 %0 扩充到一个文件名和扩展名
  • %~fs0 仅将 %0 扩充到一个带有短名的完整路径名
  • %~dp$PATH:0 查找列在路径环境变量的目录,并将 %I 扩充到找到的第一个驱动器号和路径。
  • %~ftza0 将 %0 扩充到类似输出线路的 DIR
  • %0 为当前批处理文件。如果0换成1为第一个文件,2为第2个

if-else

IF [NOT] ERRORLEVEL number command
IF [NOT] string1==string2 command
IF [NOT] EXIST filename commnd
if () else ()
if () else if () else()
if () ^
else if () ^
else ()
  • NOT 将表达式的结果取反。
  • ERRORLEVEL number 如果最后运行的程序返回一个等于或大于指定数字的退出代码。
  • string1==string2 如果指定的字符串 string1 等于 string2。
  • EXIST filename 如果指定的文件名存在。
  • command 如果符合条件(即表达式为TRUE),指定要执行的命令。如果指定的条件为 FALSE,命令后可跟 ELSE 命令,该命令将在 ELSE 关键字之后执行该命令。

扩展

IF [/I] string1 compare-op string2 command
IF CMDEXTVERSION number command
IF DEFINED variable command

其中, compare-op 可以是:

  • EQU - 等于
  • NEQ - 不等于
  • LSS - 小于
  • LEQ - 小于或等于
  • GTR - 大于
  • GEQ - 大于或等于

/I 则表示不区分大小写。

CMDEXTVERSION 条件的作用跟 ERRORLEVEL 的一样,除了它是在跟与命令扩展有关联的内部版本号比较。第一个版本是 1。每次对命令扩展有相当大的增强时,版本号会增加一个。命令扩展被停用时,CMDEXTVERSION 条件不是真的。

如果已定义环境变量,DEFINED 条件的作用跟 EXIST 的一样,除了它取得一个环境变量,返回的结果是 true。

goto

REM 跳转到 myLabel 标签
goto myLabel

REM 语句1(在 myLabel 之前的语句将不会执行)
REM 定义了一个标签
:myLabel
REM 语句2(执行该语句,因为 goto 跳转到了 myLabel 标签)

for

REM 在 CMD 窗口中
FOR %variable IN (set) DO command [command-parameters]

REM 在批处理文件中
FOR %%variable IN (set) DO command [command-parameters]
  • %variable 指定一个单一字母可替换的参数,该参数用来存放 for 语句每次迭代的数据。
  • (set) 指定一个或一组文件,可以使用通配符。
  • command 指定对每个文件执行的命令。
  • command-parameters 为特定命令指定参数或命令行开关。

/d 扩展

使用后,将于目录名匹配而不是默认的文件名。

/r 扩展

FOR /R [[drive:]path] %variable IN (set) DO command [command-parameters]

将递归进入根目录树 [Drive:]Path,在树的每个目录中执行 for 语句。如果在 /R 后没有指定目录,则认为是当前目录。如果 set 只是一个句点(.),则只枚举目录树。

/l 扩展

FOR /L %variable IN (start,step,end) DO command [command-parameters]

for /L 表示以增量形式从 start 以每次增加 step,直到到 end 的一个数字序列。如果 start 小于 end,就会执行该命令。如果迭代变量超过 end,则命令解释程序退出此循环。还可以使用负的 step 以递减数值的方式逐步执行此范围内的值。其他参数说明:

  • start:指定创建序列的开始位置
  • step:for 语句创建序列时单步距离。
  • end:指定创建序列结束位置

/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]

/F 扩展是 for 语句最常用的、也是最强的命令。主要用来处理文件和一些命令的输出结果。它可以提取文本文件的内容,进行逐行分析和处理。

file-set 为一个或多个文件名。for 语句会逐一分析指定的每个文件,打开指定文件、读取并处理文件内容。处理包括读取文件内容,将文件内容逐行读取,然后将每行解析成零或更多的符号(默认使用空格作为分隔符)。

高级选项
  • eol=[string]

    会忽略以指定 string 开头的行。不进行处理。

  • skip=[number]

    会跳过开头 number 行。

  • delims=[string]

    指定 string 符号为分割符号集合(多个字符时,空格放在最后),并替换默认的空格和制表符。

  • tokens=x,y,m-n

  • tokens=m 表示提取第m列;

  • tokens=m,n 表示提取第m列和第n列;

  • tokens=m-n 表示提取第m列至第n列;

  • tokens=* 忽略行首的所有空格;

  • tokens=m* 提取第m列以后的所有字符,星号表示剩余的字符;

/f 扩展 usebackq 选项

usebackq 命令的功能和意义不是很明朗,据说是由机器自动添加进去的,因此它变得可有可无,我们写代码时可无,机器执行时可有。但可以肯定的是,启用该选项时,它会改变“FOR /F“解析文本的功能,集合内原有引号功能失效,因此需要变成新的引号。

FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do @echo %i %j %k

goto end
会分析 myfile.txt 中的每一行,忽略以分号打头的那些行,将每行中的第二个和第三个符号传递给 for 函数体,用逗号和/或空格分隔符号。请注意,此 for 函数体的语句引用 %i 来获得第二个符号,引用 %j 来获得第三个符号,引用 %k 来获得第三个符号后的所有剩余符号。对于带有空格的文件名,你需要用双引号将文件名括起来。为了用这种方式来使用双引号,还需要使用 usebackq 选项,否则,双引号会被理解成是用作定义某个要分析的字符串。

%i 在 for 语句中显式声明,%j 和 %k 是通过tokens= 选项隐式声明的。可以通过 tokens= 一行指定最多 26 个符号,只要不试图声明一个高于字母 "z" 或"Z" 的变量。请记住,FOR 变量是单一字母、分大小写和全局的变量;而且,不能同时使用超过 52 个(a-zA-Z 等于 26+26)。
:end

学习 Bat 脚本
http://localhost:8080/archives/ae44a083-d4cc-4872-a32b-57b5cbb57a7f
作者
inksha
发布于
2024年09月14日
许可协议