扩展符号,对于变量%1,可以这样使用%~x1:取变量的扩展名。支持的扩展列表:
%~1 扩展 %1 并删除任何引号 ("")
%~f1 将 %1 扩展到全限定的路径名
%~d1 将 %1 扩展到驱动器盘符
%~p1 将 %1 扩展到路径
%~n1 将 %1 扩展到文件名
%~x1 将 %1 扩展到文件扩展名
%~s1 扩展的路径仅包含短名称
%~a1 将 %1 扩展到文件属性
%~t1 将 %1 扩展到文件日期/时间
%~z1 将 %1 扩展到文件大小
%~$PATH:1 搜索 PATH 环境变量中列出的目录,并将 %1 扩展到第一个找到的目录的完全限定名称。如果没有定义环境变量名称,或没有找到文件,则此符号扩展成空字符串
获取bat所在目录的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
rem 将第一个命令的输出作为第二个命令的输入
command1
>
commana2
rem 将输出发送到指定的文件,必要的时候需要创建该文件或重写
command
>
[
path
]
filename
rem 将输出附加到指定的文件(如果该文件存在),或者创建该文件并向其写入
command
>>
[
path
]
filename
rem 从指定的文件中获取命令的输入,之后将命令的输出发送到指定的文件
command
<
[
path
]
filename
>
[
path
]
filename
rem 从指定的文件中获取命令的输入,之后将命令的输出附加到指定的文件
command
<
[
path
]
filename
>>
[
path
]
fllename
rem 创建指定的文件,之后将错误输出发送到该文件。如果该文件存在,则其内容会被重写
command
2
>
[
path
]
filename
rem 将错误输出信总发送到标准输出
command
2
>
&
1
rem 将标准错误丢弃,不显示
command
2
>
nul
rem 从指定的文件路径中提取命令的输入信息
command
<
[
path
]
filename
在一个批处理程序中调用另外一个,执行完毕后返回CALL :label arguments,调用当前批处理文件内的命令段——:label开头,以命令goto :eof结尾的部分
START
在新的命令行窗口中执行程序,命令格式:start ["title"] [/dPath] [/i] [/min] [/max] [{/separate | /shared}] [{/low | /normal | /htgh | /realtime | /abovenormal | belownormal}] [/wait] [/b] [FileName] [parameters]
title:指定在“命令提示符”窗口标题栏中显示的标题
/dPath:指定启动目录
/i:将Cmd.exe启动环境传送到新的“命令提示符”窗口
/min:启动新的最小化“命令提示符”窗口
/max:启动新的最大化“命令提示符”窗口
/separate:在单独的内存空间启动16位程序
/shared:在共享的内存空间启动16位程序
/low:以空闲优先级启动应用程序
/normal:以一般优先级启动应用程序
/high:以高优先级启动应用程序
/realtime:以实时优先级启动应用程序
/abovenormal:以超出常规优先级的方式启动应用程序
/bdownormal:以低出常规优先级的方式启动应用程序
/wait:启动应用程序,并等待其结束
/b:启动应用程序时不必打开新的“命令提示符”窗口
FileName:指定要启动的命令或程序
parameters:指定要传送给命令或程序的参數
set命令用于创建、设置或者删除环境变量,命令格式:
set
[
[
/
a
[
expression
]
]
[
/
p
[
variable
=
]
]
string
]
参数说明:
/
a
:将string设置成可求值的数学表达式,expression:合法的表达式,表达式支持的运算符按优先级降序如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
REM 文件存在性测试(注意,不能用来测试环境变量)
IF
[
NOT
]
EXIST
FILENAME
.
EXT
Command
if
not
exist
SERVICE
_
NAME
&
nbsp
;
set
"SERVICE_NAME=%SERVICE_NAME_DEFAULT%"
REM 如果有多行命令需要执行,可以用()包围:
set
/
p
VENDER
_
NAME
=
IF
NOT
Gmem
=
VENDER
_
NAME
(
echo
.
)
REM 变量是否为空测试
IF
DEFINED
VAR
_
NAME
(
.
.
.
)
REM 字符串为空测试,这个用于stdin读入变量无效
IF
[
%1
]
==
[
]
ECHO
"Empty argument."
REM 字符串相等性测试,加上双引号避免歧义
IF
"%VAR_NAME%"
==
"1"
ECHO
.
REM 注意,如果VAR_NAME来自标准输入,或者可能为空,要加上双引号,否则可能出现
REM was unexpected at this time(此时不应有)错误
REM 如果字符串可能有空格,可以使用双引号,例如 "AUTOEXE .BAT","%1"(第一个参数)
IF
[
NOT
]
%1
==
AUTOEXEC
.
BAT
ECHO
Parameter is AUTOEXEC.BAT
REM 上一条命令返回值测试
REM 其中值为整数,只要大于等于该值,判断为真。0表示没有错误
IF
[
NOT
]
ERRORLEVEL
值
Command
REM 比较字符串大小:op可以是:EQU、NEQ、LSS、LSQ、GTR、GEQ之一,/i表示忽略大小写
if
[
/
i
]
stringl
op
string2
command
[
else
expression
]
REM 如果变量被定义,则执行
if
defined
variable
command
[
else
expression
]
REM IF-ELSE结构
IF
EXIST
filename
(
del
filename
)
ELSE
(
echo
filename missing
)
%variable|%%variable:代表可替换的参教:
使用
%variable通过命令提示符
执行for 命令,使用
%%variable在批处理文件
执行for命令
set:指定要用命令处理的
一个或多个文件、目录、数值范围或文本字符串
command:指定要对包括在指定(set)中的每个文件、目录、数值范围或文本字符 串所执行的命令
CommandLineOptions:命令使用的命令行选项
for命令的不同形式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
@echo
off
set
/
a
sum
=
0
REM 遍历当前目录中的文本文件并打印其内容,多行命令需要用()包围
for
%
%
x
in
(
*
.
txt
)
do
(
echo
Printing content of file %%x
type
%
%
x
echo
.
set
/
a
sum
=
sum
+
1
REM 从0开始,步进2,到10结束
for
/
L
%
%
B
in
(
0
2
,
10
)
do
echo
%%B
REM 下面的语句首先会运行date /t命令,其输出为类似:“2001/01/01 周一”这样的形式
REM /F 表示以字符串方式处理命令输出、字符串或者文件内容
REM tokens用于定义for命令的变量个数,1-3表示第1、2、3个字符串并解析为变量
REM delims表示用于拆分字符串的分隔符,包括/、-
REM set表示把拆分的字符串依次赋值给%%A %%B %%C三个变量(后面的变量名在前面的ASCII码加1)
REM delims可以指定多个字符用于分隔
for
/
F
"tokens=l-3 delims=/-"
%
%
A
in
(
'date /T'
)
do
set
date
=
%
%A%
%B%
%
C
rem 提取NT Service的PID的例子,注意sc queryex命令输出多行
rem 下面的for命令以行为单位进行处理,并提取第一列、第三列
rem skip可以用于跳过指定数量的行
for
/
F
"tokens=1,3 skip=3"
%
%
a
in
(
'sc queryex Tomcat7'
)
do
(
echo
%%a %%b
)
rem usebackq允许在源指定符中使用引号;eol指定行尾结束字符,之后的内容被忽视
for
/
f
"tokens=3-5 usebackq eol=#"
%
%
C
in
(
"user data.txt"
)
do
echo
%%C
rem 命令输出如下:
rem SERVICE_NAME:
rem TYPE 110
rem STATE 4
rem (STOPPABLE, ACCEPTS_SHUTDOWN)
rem WIN32_EXIT_CODE 0
rem SERVICE_EXIT_CODE 0
rem CHECKPOINT 0x0
rem WAIT_HINT 0x0
rem PID 5812
rem FLAGS
REM tokens更复杂的例子
REM tokens=x 表示只提取第x列。
REM tokens=x,y 表示只提取第x列和第y列。
REM tokens=m-n 表示提取第m列至第n列。
REM tokens=x* 表示提取第x列和后面所有字符串都作为第x+1列。
REM tokens=x,* 等同tokens=x*
REM tokens=x,y,m-n 表示提取第x,y列以及第m至第n列。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@echo
off
REM 这样才能将循环变量%%a赋值给环境变量
setlocal
enabledelayedexpansion
title
fuckbat
REM 遍历命令结果的2、10列
for
/
f
"delims=, tokens=2,10"
%
%
a
in
(
'tasklist /NH /V /FI "IMAGENAME eq cmd.exe" /FO CSV'
)
do
(
REM 将循环变量赋值
set
task
_
title
=
title
%
%
b
set
pid
=
%
%
a
REM 脱去外部的双引号,用!!的界定符访问变量pid, pid:"= 表示将pid中的"替换为空
set
pid
=
!
pid
:
"=!
REM 如果将标题中的fuckbat替换为空后得到的值与之前不等,说明标题中有fuckbat,说明当前迭代的时当前进程
if not "
!
task
_
title
!
"=="
!
task
_
title
:fuckbat
=
!
"
(
echo
!pid! > pid.txt
)
)
endlocal
批处理读取命令时是按行读取的(另外例如for命令等,其后用一对
圆括号闭合的所有语句也当作一行
)
为了能够感知环境变量的动态变化,批处理设计了变量延迟——在读取了一条完整的语句之后,不立即对该行的变量赋值,而会在某个单条语句执行之前再进行赋值
使用变量延迟扩展来处理环境变量中的特殊字符