基本语法
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.