基本语法
set 设置变量
作用:显示、设置或删除环境变量。
1 | set [<Variable>=[<String>]] |
Variable
指定环境变量名,String
表示指派给变量的字符串。
注意:=
前不能有空格,否则无法设置变量。后面可以有空格,但是空格包含在字符串内,例如:set p=abc
,p
的值为 abc
;set p= abc
,p
的值为 _abc
(下划线表示空格)。
基础用法
set
, 显示目前所有可用的变量,包括系统变量和自定义的变量。set p
,显示所有以p
开头的变量,要是一个也没有的话就设errorlevel=1
。set p=abcdefgh
,设置变量p
,并赋值为=
后面的字符串,即abcdefgh
。set /a p=42
,设置p
为数值型变量,值为42
。set /a p=42/10
,支持运算符,运算后取整,p=42/10=4.2=4
。set p=
,取消p
变量。set /p p=
,将变量的值设置为用户输入的输入行。set /p p=input:
,在屏幕上显示input:
,并将用户输入行作为p
的值。
变量的引用即赋值
例,设有 set p=abcdefgh
。
echo %p%
,显示p
的值,即abcdefgh
。echo %p:~3%
,显示p
的第 3 个字符以后的所有字符,即defgh
。echo %p:~3,3%
,显示p
的第 3 个字符以后的 3 个字符,即def
。echo %p:~0,3%
,显示p
的前 3 个字符,即def
。echo %p:~-2%
,显示p
的最后 2 个字符,即gh
。echo %p:~0,-2%
,显示p
的第 1 个字符到最后 2 个字符之前的所有字符,即abcdef
。echo %p:a=i%
,将p
中的a
替换为i
,即ibcdefgh
。echo %p:b=%
,将p
中的b
替换为空,即acdefgh
。echo %p:*cd=j%
,将p
中的cd
及之前的字符替换为j
,即jefgh
。set q=%p:*e=k%
,将p
中的e
及之前的字符替换为k
并设置为变量q
,q
的值为kfgh
。
常见变量
%CD%
,代表当前目录的字符串。%DATE%
,当前日期。%TIME%
,当前时间。%RANDOM%
,随机整数,介于 0~32767。%ERRORLEVEL%
,当前 ERRORLEVEL 值。
setlocal
默认 bat 文件中的变量是全局的,也就是说在一个 bat 文件中创建的变量,在程序的任何地方都可以访问。
使用 setlocal
和 endlocal
来设定变量的作用域,在这两个之间出现的变量属于局部变量。
例:
1 | @echo off |
setlocal enabledelayedexpansion
批处理读取命令是按行读取,处理每行命令前会对语句做预处理,所以变量的值会在预处理时设置。有点类似于 C 语言中的宏替换。
例如:
1 | set var1=foo |
虽然使用了 set var1=bar
,但是输出的还是 foo
。
这时开启 setlocal enabledelayedexpansion
,可以获取到变量的运行时的值,同时取变量是需要用 !var1!
来取值。
例如:
1 | setlocal ENABLEDELAYEDEXPANSION |
这时输出的值为 bar
。
批处理参数
批处理的参数可以用 %*
(%0, %1, %2...
)来引用,索引 0 表示当前执行的脚本文件,索引 1 以后表示其他参数(升序)。
批处理参数 | 说明 |
---|---|
%~1 |
展开 %1 并删除周围的引号(””)。 |
%~f1 |
将 %1 扩展到完全限定的路径。 |
%~d1 |
仅将 %1 扩展到驱动器号。 |
%~p1 |
仅将 %1 展开为路径。 |
%~n1 |
仅将 %1 扩展到文件名。 |
%~x1 |
仅将 %1 扩展到文件扩展名。 |
%~s1 |
将 %1 扩展到仅包含短名称的完全限定路径。 |
%~a1 |
将 %1 扩展到文件属性。 |
%~t1 |
将 %1 扩展到文件的日期和时间。 |
%~z1 |
将 %1 扩展到文件的大小。 |
%~$PATH:1 |
搜索 PATH 环境变量中列出的目录,并将 %1 扩展到找到的第一个目录的完全限定名称。 如果未定义环境变量名称或搜索找不到该文件,则此修饰符将扩展为空字符串。 |
带有修饰符的批处理参数 | 说明 |
---|---|
%~dp1 |
将 %1 扩展到驱动器号和路径。 |
%~nx1 |
仅将 %1 扩展到文件名和扩展名。 |
%~dp$PATH:1 |
搜索 %1 的 PATH 环境变量中列出的目录,然后扩展到找到的第一个目录的驱动器号和路径。 |
%~ftza1 |
展开 %1 以显示类似于 dir 命令的输出。 |
for
命令
语法
1 | for { %%|%}<Variable> in (<Set>) do <Command> |
参数 | 描述 | |
---|---|---|
`{ %% | %} |
Variable 变量。表示可替换参数。命令行下使用 % ,批处理文件中使用 %% 。变量区分大小写,必须使用字母值(例如:%A, %B, %C )。 |
<Set> |
范围,需要括号括起来。 | |
<Command> |
在每个循环中执行的命令。 |
备注
<Set>
参数指定一组文件,可以使用通配符(*?
),例如:
1 | (*.doc) |
扩展参数
/d
,仅目录。/r
,遍历整个目录树,包括子目录树。如果<Set>
为.
,则只遍历目录。语法:
1 | for /r [[<Drive>:]<Path>] {%%|%}<Variable> in (<Set>) do <Command> |
假设目录为
1 | E:\ |
1 | # /d 显示所有以 folder 开头的文件夹 |
/l
,遍历值,从起始值(Start
)到结束值(End
)。例如:(1,1,5)
生成1 2 3 4 5
,(5 ,-1,1)
生成5 4 3 2 1
。语法:
1 | for /l {%%|%}<Variable> in (<Start>,<Step>,<End>) do <Command> |
/f
,遍历文本文件中的文本。语法:
1 | for /f [<ParsingKeywords] {%%|%}<Variable> in (<Set>) do <Command> |
ParsingKeywords
关键字:
关键字 | 描述 |
---|---|
eol=<c> |
指定行尾字符(仅一个字符)。 |
skip=<N> |
指定文件开头要跳过的行数。 |
delims=<xxx> |
指定分隔符集。默认为i空格和制表符。 |
tokens=<X,Y,M-N> |
指定每行的哪些标记要传递到循环中。 |
例子:
文件 text1.txt 内容如下:
1 | line no 1 first |
1 | # 打印 text1.txt 的内容,只打印出了第一个单词,因为默认分隔符是空格,遍历每行时只获取到第一个变量 |
其他
获取路径
常用变量
%cd%
,当前执行脚本的目录路径。%~d0
,脚本文件所在的盘符。%~dp0
,脚本文件所在的目录路径。%~df0
,脚本文件的文件路径。%0
,脚本文件的文件路径字符串,比%~df0%
多了引号。%~0
,同%~df0
。
其他可参见:批处理参数。
例:文件结构如下:
1 | D: |
test.bat 文件内容如下
1 | @echo off |
在 D:\dirA
目录下执行 test.bat
文件:
1 | D:\dirA>test.bat |
输出结果为:
1 | D:\dirA |
获取文件夹、文件名、不带扩展名的文件名。
1 | set filepath="C:\some path\having spaces.txt" |
中文乱码
- 方法一:将 bat 文件存为 ANSI 编码
- 方法二:在文件开始声明编码
1 | rem 声明采用UTF-8编码 |
参考链接
- 批处理中set设置变量, by Turbo_J.
- 设置, docs.microsoft.com.
- Batch file variables and scope, aticleworld.com.
- 批处理中setlocal enabledelayedexpansion的作用详细整理, jbt1.net.
- Ciantic/dirname-filename-basename.bat, github.com.
- Resolve absolute path from relative path and/or file name, stackoverflow.com.
- call, docs.microsoft.com.
- for, doc.microsoft.com.