Bat批处理命令

856 阅读20分钟

什么是bat?

批处理(Batch,简称 bat)是一系列 Dos 命令按照一定的顺序组成的一个可执行文件,后缀名是 .bat 或者 .cmd,其常用于 Dos 或者 Windows 系统,通常我们是指 Dos 脚本。

命令查看地址:www.yiibai.com/batch_scrip…

注意事项:
1.文件保存格式为ANSI(后果:导致中文乱码或执行命令不生效)。
2.以管理员身份运行文件(后果:否则无法执行或执行无反应)。
3.以ANSI格式保存后执行出现乱码,需要重新再次以ANSI格式保存后然后再次执行。

常用命令

如果对某一个命令不熟悉,可以在命令行窗口下输入:命令名/?的方式来获得帮助。 例如:dir /?

@echo

@                    #关闭单行回显。
echo off             #从下一行开始关闭回显。
@echo off            #从本行开始关闭回显。
echo on              #从下一行开始打开回显,默认是 echo on 
echo                 #用于输出信息,默认会将命令本身也输出。
echo.                #输出一个"回车换行",一般就是指空白行。
echo hello world     #输出hello world。

关闭回显"是指运行批处理文件时,不显示文件里的每条命令,只显示运行结果批处理开始和结束时,系统都会自动打开

描述:在批处理中echo用于输出信息,默认会将命令本身也输出。

errorlevel

每个命令运行结束,可以用这个命令行格式查看返回码用于判断刚才的命令是否执行成功默认值为 0 ,一般命令执行出错会设置 errorlevel 为 1。

echo %errorlevel%

dir

显示当前目录中的文件和子目录

dir                 #显示当前目录中的文件和子目录
dir /a              #显示当前目录中的文件和子目录,包括隐藏文件和系统文件
dir c: /a:d         #显示 C 盘当前目录中的目录
dir c:\ /a:-d       #显示 C 盘根目录中的文件
dir d:\mp3 /b/p     #逐屏显示 d:\mp3 目录里的文件,只显示文件名,不显示时间和大小。
dir *.exe /s        #显示当前目录和子目录里所有的.exe文件其中 * 是通配符,代表所有的文件名。
                    #还有一个通配符 ? 代表一个任意字母或汉字,如 c*.* 代表以 c 开头的所有文件。
                    #?.exe 代表所有文件名是一个字母的.exe文件。
                    #如果指定的目录或文件不存在,将返回 errorlevel 为1。
                    #每个文件夹的 dir 输出都会有2个子目录 。
                    #. 和 ... 代表当前目录。
                    #.. 代表当前目录的上级目录。
dir .               #显示当前目录中的文件和子目录
dir ..              #显示当前目录的上级目录中的文件和子目录

cd

cd mp3              #进入当前目录中的mp3目录。
cd ..               #进入当前目录中的上级目录。
cd \                 #进入根目录。
cd                  #显示当前目录。
cd /d d:\mp3        #可以同时更改盘符和目录,要跳转到不同分区的时候,需要添加强制跳转参数 /d 
cd "Documents and Settings"\All users	#文件名带空格,路径前需要加上引号,如果更改到的目录不存在,则出错返回 errorlevel=1。

md

md abc              #在当前目录里建立子目录abcmd d:\a\b\c         #如果 d:\a 不存在,将会自动创建。

rd

rd abc              #删除当前目录里的 abc 子目录,要求为空目录。
rd /s/q d:\temp     #删除 d:\temp 文件夹及其子文件夹和文件,不需要按 Y 确认。

del

del d:\test.txt           #删除指定文件,不能是隐藏、系统、只读文件。
del *.*                   #删除当前目录里的所有文件,不包括隐藏、系统、只读文件,要求按 Y 确认。
del /q/a/f d:\temp\*.*    #删除 d:\temp 文件夹里面的所有文件,包括隐藏、只读、系统文件,不包括子目录。
del /q/a/f/s d:\temp\*.*  #删除 d:\temp 及子文件夹里面的所有文件,包括隐藏、只读、系统文件,不包括子目录。

ren

ren 1.txt 2.bak     #把 1.txt 更名为 2.bak。
ren *.txt *.ini     #把当前目录里所有.txt文件改成.ini文件。
ren d:\temp tmp     #支持对文件夹的重命名。

cls

cls	          #清屏效果。

type

type c:\boot.ini    #显示指定文件的内容,程序文件一般会显示乱码。
type *.txt          #显示当前目录里所有.txt文件的内容。

copy

copy c:\test.txt d:\           #复制 c:\test.txt 文件到 d:\。
copy c:\test.txt d:\test.bak   #复制 c:\test.txt 文件到 d:\ ,并重命名为 test.bak。
copy c:\*.*                    #复制 c:\ 所有文件到当前目录,不包括隐藏文件和系统文件不指定目标路径,则默认目标路径为当前目录。
copy con test.txt              #从屏幕上等待输入,按 Ctrl+Z 结束输入,输入内容存为test.txt文件con代表屏幕,prn代表打印机,nul代表空设备。
copy 1.txt + 2.txt 3.txt       #合并 1.txt 和 2.txt 的内容,保存为 3.txt 文件如果不指定 3.txt ,则保存到 1.txt。
copy test.txt +                #复制文件到自己,实际上是修改了文件日期。

title

title 新标题                   #改变cmd窗口的标题栏。

color [16进制颜色格式]

设置批处理控制台背景颜色与字体颜色。
0=黑、1=蓝、2=绿、3=浅绿、4=红、5=紫、6=黄、7=白、8=灰、9=淡蓝、A=淡绿、B=淡浅绿、C=淡红、D=淡紫、E=淡黄、F=亮白。

color 74           #白底红字体。
color 0A           #黑底淡绿字体。

ver

ver                 #显示当前系统版本。

labelvol

vol                 #显示卷标。
label               #显示卷标,同时提示输入新卷标。
label c:system      #设置C盘的卷标为 system。

pause

pause       	   #运行该命令时,将显示下面的消息:请按任意键继续 . . .,一般用于看清楚屏幕上显示的内容。

rem::

rem::为注释命令,但是不同的是::后的字符在执行时不会回显,无论是否用echo no打开命令行回显状态,因为命令解释器不认为它是一个有效的命令行。

有效标号冒号后紧跟一个以字母数字开头的字符串,goto语句可以识别到。
无效标号冒号后紧跟一个以非字母数字开头的特殊字符,goto语句无法识别的标号,可以起到注释作用。

rem		    #注释行不执行操作。
::                  #注释行不执行操作。

datetime

date          		#显示当前日期,并提示输入新日期,按"回车"略过输入。
date/t        		#只显示当前日期,不提示输入新日期。
time          		#显示当前时间,并提示输入新时间,按"回车"略过输入。
time/t       		#只显示当前时间,不提示输入新时间。

goto:

:label        		#行首为:表示该行是标签行,标签行不执行操作。
goto label    		#跳转到指定的标签那一行。

find

find "abc" c:\test.txt	#在 c:\test.txt 文件里查找含 abc 字符串的行如果找不到,将设 errorlevel 返回码为1。
find /i "abc" c:\test.txt	#查找含 abc 的行,忽略大小写。
find /c "abc" c:\test.txt	#显示含 abc 的行的行数。

more

more c:\test.txt    #逐屏显示 c:\test.txt 的文件内容。

tree

tree d:\            #显示D盘的文件目录结构。
tree>list.txt	    #把信息导入到文件中。

&

顺序执行多条命令,而不管命令是否执行成功。

c: & cd\ & dir /w	#相当于把3行命令当作一行命令执行。

&&

顺序执行多条命令,当碰到执行出错的命令后将不执行后面的命令。

f: && cd\ && dir >c:\test.txt             #注意如果f盘不存在,那么后面2条命令将不会执行。
find "ok" c:\test.txt && echo 成功        #如果找到了"ok"字样,就显示"成功",找不到就不显示。

|

前一个命令的执行结果输出到后一个命令。

dir *.* /s/a | find /c ".exe"		#管道命令表示先执行 dir 命令,对其输出的结果执行后面的。                                             #find 命令该命令行结果:输出当前文件夹及所有子文件夹里的.exe文件的个数。与type c:\test.txt|more这个和 more c:\test.txt 的效果是一样的。

||

顺序执行多条命令,当碰到执行正确的命令后将不执行后面的命令。

find "ok" c:\test.txt || echo 不成功    #如果找不到"ok"字样,就显示"不成功",找到了就不显示。

>>>

>                                #清除文件中原有的内容后再写入。
>>                               #追加内容到文件末尾,而不会清除原有的内容主要将本来显示在屏幕上的内容输出到指定文件中,指定文件如果不存在,则自动生成该文件。
echo hello world>c:\test.txt    #生成c:\test.txt文件,内容为hello world这个格式在批处理文件里用得很多,可以生成.reg .bat .vbs 等临时文件。
type c:\test.txt >prn           #屏幕上不显示文件内容,转向输出到打印机。
echo hello world>con            #在屏幕上显示hello world,实际上所有输出都是默认 >con 的。
copy c:\test.txt f: >nul        #拷贝文件,并且不显示"文件复制成功"的提示信息,但如果f盘不存在,还是会显示出错信息。
copy c:\test.txt f: >nul 2>nul  #不显示"文件复制成功"的提示信息,并且f盘不存在的话,也不显示错误提示信息。
echo ^^W ^> ^W>c:\test.txt      #生成的文件内容为 ^W > W^ 和 > 是控制命令,要把它们输出到文件,必须在前面加个 ^符号。

<

@echo off 
echo 2005-05-01>temp.txt 
date <temp.txt 			#这样就可以不等待输入直接修改当前日期。
del temp.txt		

%0 %1 %2 %3 %4 %5 %6 %7 %8 %9 %*

命令行传递给批处理的参数,

  • %0 : 批处理文件本身。包括完整的路径以及扩展名。
  • %1 : 第一个参数。
  • %9 : 第九个参数。
  • %* : 从第一个参数到第九个参数。 参数%0具有特殊功能,可以调用批处理自身以达到批处理本身循环的目的,也可以复制文件自身等等。
@echo off
echo %0
echo %1
echo %2
echo %*

set

set设置变量,引用变量可在变量名前后加 % ,即 %变量名%。

set                    #显示目前所有可用的变量,包括系统变量和自定义的变量。
echo %SystemDrive%     #显示系统盘盘符。系统变量可以直接引用。
set p                  #显示所有以p开头的变量,要是一个也没有就设errorlevel=1。
set p=aa1bb1aa2bb2     #设置变量p,并赋值为 = 后面的字符串,即aa1bb1aa2bb2。
echo %p%               #显示变量p代表的字符串,即aa1bb1aa2bb2。
echo %p:~6%            #显示变量p中第6个字符以后的所有字符,即aa2bb2。
echo %p:~6,3%          #显示第6个字符以后的3个字符,即aa2。
echo %p:~0,3%          #显示前3个字符,即aa1。
echo %p:~-2%           #显示最后面的2个字符,即b2。
echo %p:~0,-2%         #显示除了最后2个字符以外的其它字符,即aa1bb1aa2b。
echo %p:aa=c%          #用c替换变量p中所有的aa,即显示c1bb1c2bb2。
echo %p:aa=%           #将变量p中的所有aa字符串置换为空,即显示1bb12bb2。
echo %p:*bb=c%         #第一个bb及其之前的所有字符被替换为c,即显示c1aa2bb2。
set p=%p:*bb=c%        #设置变量p,赋值为 %p:*bb=c% ,即c1aa2bb2。
set /a p=39            #设置p为数值型变量,值为39。
set /a p=39/10         #支持运算符,有小数时用去尾法,39/10=3.9,去尾得3,p=3。
set /a p=p/10          #用 /a参数时,在 = 后面的变量可以不加%直接引用。
set /a p="1&0"         #"与"运算,要加引号。其它支持的运算符参见set/?。

""

""表示字符串界定符,双引号在允许字符串中包含空格,进入一个特殊的目录可以用以下方法。

cd "program files"
cd  progra~1
cd "pro*
#以上方法都可以进入program files文件夹中。

逗号相当于空格,在某些情况下","可以用来当作空格使用。

dir,C:\             #相当于dir :\

;

当命令相同时,可以将不同目标用来隔离开来,但执行效果不变,如果执行过程中发生错误,则只返回错误报告,但程序仍然会执行。

比如:dir c:\;d\;e\ #相当于 dir c:\  dir d:\  dir e:\

%

%表示变量引导符,这个%严格来说算不上命令,他只是批处理中的参数而已(多个%一起使用的情况除外)。
引用变量%var%,调用程序外部参数%1%9等等。

set i = 武科
echo %i%              #就会显示武科

^

^是对特殊符号<>&的前导字符,在命令中可以将它们的特殊功能去掉,仅仅将他们当成符号而不使用它们的特殊意义。

echo test^>2.txt      #他没有添加内容到2.txt中,只是显示了出来。

()

小括号在批处理编程中有特殊作用,左右括号必须成对使用,括号中可以包括多行命令,这些命令被看作一个整体,被视为一条命令。括号在for语句和if语句中常见,用来嵌套使用循环或条件语句,其实括号也可以单独使用。

echo 1  echo2  echo 3)  #相当于echo 1 & echo2 & echo 3 

start

批处理中调用外部程序的命令,否则等外部程序完成后才继续执行剩下的指令。

start explorer d:\                                  #调用图形界面打开D盘。
@echo off 
cd /d %~dp0regedit /s 劲舞团.reg start patcher.exe  #不加 start 命令的话,"劲舞团"运行时,后面会有个黑乎乎的cmd窗口。

call

批处理中调用另外一个批处理的命令,否则剩下的批处理指令将不会被执行有时有的应用程序用start调用出错的,也可以call调用。

call c:\code\run.bat	#执行另一个批处理文件。

xcopy

xcopy d:\mp3 e:\mp3 /s/e/i/y	#复制 d:\mp3 文件夹、所有子文件夹和文件到 e:\ ,覆盖已有文件加 /i 表示如果没有 e:\mp3 文件夹就自动新建一个,否则会有询问。	

format

format c: /q/u/autotest       #/q表示快速格式化,/autotest表示自动格式化,不需要按 Y 确认/u表示每字节用	F6 覆盖硬盘数据,使其不可用软件恢复。
format c: /c                  #格式化C盘,并检测坏道。

ping

ping -l 65500 -t 192.168.1.200        #不停的向192.168.1.200计算机发送大小为65500byte的数据包。
ping -n 10 127.0.0.1>nul              #ping自己10次,可用于批处理延时10秒。

attrib

attrib a.txt                         #显示位于当前目录中的a.txt的文件的属性
attrib +r a.txt                      #添加只读属性
attrib -r d:\public\*.* /s           #删除public目录及其子目录的文件只读属性
attrib +a d:*.* & attrib -a d:*.bak  #为驱动器d:上的所有文件设置 Archive 属性,然后清除具有 .bak 扩展名的文件的 Archive 属性

SC

#创建服务,服务名称aaa,显示名称bbb,启动类型:自动可执行文件的路径"C:\WINDOWS\System32\alg.exe"
sc create aaa displayname= bbb start= auto binpath= "C:\WINDOWS\System32\alg.exe"
#更改aaa的描述为ccc
sc description aaa "ccc"
#更改aaa的启动类型:已禁用更改aaa的可执行文件的路径"C:\WINDOWS\System32\svchost.exe -k netsvcs"
sc config aaa start= disabled binpath= "C:\WINDOWS\System32\svchost.exe -k netsvcs"
#更改aaa的启动类型:手动更改aaa的显示名称ddd
sc config aaa start= demand displayname= ddd
#启动aaa服务
sc start aaa
#停止aaa服务
sc stop aaa
#删除aaa服务
sc delete aaa

IF

语法格式:if "字符串1"=="字符串2" command 语句`。

判断两个字符串是否相等

语法格式:if 数值1 equ 数值2 command 语句

判断两个数值是否相等

语法格式:if exist filename command 语句

判断判断驱动器,文件或文件夹是否存在

语法格式:if defined 变量 command 语句

判断变量是否已经定义

语法格式:if errorlevel 数值 command 语句

判断上个命令的返回值

判断字符串是否相等的时候,if会区分大小写,比如,单纯的if语句会认为字符串abc和字符串Abc不相同,若不想区分大小写,则需要添/i加开关,使用 if /i “字符串1"=="字符串2" 的格式; 另外,等于符号是连续的"=="而非单独的"="

判断两个数值之间的大小关系,除了等于用equ之外,还有其他的关系符号,所有适用于if语句的关系符号见下表: image.png

# 判断文件存不存在,存在就执行,不存在则复制文件到目标再执行。可按需要改动里面的文件名,可为EXE、BAT、CMD、COM等执行文件。
@echo off 
if exist e:\123.bat goto st 
copy /y c:\123.bat e:\123.bat 
goto st 
:st 
start e:\123.bat 
exit 


# 执行后会要求你输入两个字符串,然后批处理判断它俩是否相同。在判断字符串是否相等的时候,if是会区分大小写
@echo off
if "a"=="A" (echo 输入的两个字符相同) else echo 输入的两个字符不相同
pause

#执行后会显示:输入的两个字符不相同,如果我们不想让它区分大小写,则可以加上/i 参数。
@echo off
if /i "a"=="A" (echo 输入的两个字符相同) else echo 输入的两个字符不相同
pause

FOR

语法格式:FOR %variable IN (set) DO command [command-parameters]

  • %variable, 指定一个单一字母可替换的参数。
  • (set),指定一个或一组文件,也可以一段文本内容。可以使用通配符。默认以空格,;三种符号分隔开。
  • command, 指定对每个文件执行的命令。
  • command-parameters,为特定命令指定参数或命令行开关。在批处理程序中使用for命令时,指定变量请使用%%variable而不要用%variable。变量名称是区分大小写的,所以%i不同于%I.
#遍历c盘的所有文件(不包括文件夹),然后输出到控制台。
for %%i in (c:\*.*) do @echo %%i

#以空格为分隔符,将a、b、c逐行输出到控制台。
for %%i in (a b c) do @echo %%i

#字符串加""则认为不分割,%~i不显示双引号。
for %%i in ("a b c") do @echo %%~i

#遍历所有磁盘,判断存在的并输出至控制台。
set str=c d e f g h i j k l m n o p q r s t u v w x y z
echo 当前硬盘的分区有:
for %%i in (%str%) do if exist %%i: echo %%i:

#使用通配符输出当前目录下所有后缀为.txt的文件名。
for %%i in (*.txt) do echo %%i

#使用通配符输出当前目录下所有后缀为.txt文件名只有2个字符的文件名。
for %%i in (??.txt) do echo %%i

FOR /D

语法格式:FOR /D %variable IN (set) DO command [command-parameters]

  • /d指示set中的元素为目录。如果set中包含通配符,则指定与目录名匹配,而不与文件名匹配。
#循环输出当前目录下所有的目录名。
for /d %%i in (*) do echo %%i
#循环输出当前目录下,目录名最后字符为a的所有目录名。
for /d %%i in (*a) do echo %%i

FOR /R

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

  • 检查以[drive:]path为根的目录树,指向每个目录中的FOR语句。如果在/R后没有指定目录规范,则使用当前目录。如果集仅为一个单点(.)字符,则枚举该目录树。
# 遍历当前目录下所有目录,"/\."三者效果相同
for /r %%i in (.) do @echo %%i
for /r %%i in (\) do @echo %%i
for /r %%i in (/) do @echo %%i

# 遍历指定目录
for /r e:\ %%i in (.) do @echo %%i

#遍历当前目录下所有文件并显示完全路径(包括子目录)
for /r e:\ %%i in (*) do @echo %%i
for /r e:\ %%i in (*.txt) do @echo %%i

FOR /L

语法格式: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)。
# 从1开始,以2为步进值,循环到不超过10(包括等于)。
for /l %%i in (1, 2, 10) do @echo %%i

# 从10开始,以-2为步进值,循环到不小于0(包括等于)。
for /l %%i in (10, -2, 0) do @echo %%i

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]

fileset为一个或多个文件名。继续到fileset 中的下一个文件之前,每份文件都被打开、读取并经过处理。处理包括读取文件,将其分成一行行的文字,然后将每行解析成零或更多的符号。然后用已找到的符号字符串变量值调用For循环。 以默认方式/F通过每个文件的每一行中分开的第一个空白符号。跳过空白行。 options,可通过指定可选options参数替代默认解析操作。这个带引号的字符串包括一个或多个指定不同解析选项的关键字。这些关键字为:

  • eol=c : 指一个行忽略的开始字符(就一个)。
  • skip=n : 指在文件开始时忽略的行数。
  • delims=xxx : 指分隔符集。这个替换了空格和跳格键的默认分隔符集。
  • tokens=x,y,m-n : 指每行的哪一个符号被传递到每个迭代的for本身。这会导致额外变量名称的分配。m-n格式为一个范围。通过nth符号指定mth。如果符号字符串中的最后一个字符星号,那么额外的变量将在最后一个符号解析之后分配并接受行的保留文本。
  • usebackq - 指定新语法已在下类情况中使用:在作为命令执行一个后引号的字符串并且一个单引号字符为文字字符串命令并允许在file-set中使用双引号扩起文件名称。
# 读取当前目录的a.txt,并显示每一行的内容(每一行内容遇到空格即终止)
for /f %i in (a.bat) do @echo %i

# 读取多个文件,并显示每一行的内容(每一行内容遇到空格即终止)
for /f %i in (a.bat b.txt) do @echo %i

# 忽略以"s”开头的行
for /f "eol=s“ %i in (a.bat) do @echo %i

# 跳过前5行
for /f "skip=5" %i in (a.bat) do @echo %i

# 集中的分隔符默认为空格和tab键
# 通过delims=显式指定分隔符
for /f "delims=," %i in (a.bat) do @echo %i

# 通过delims=显式指定分隔符,可以指定多个
for /f "delims=,;" %i in (a.bat) do @echo %i

# 提取分隔字符串指定部分
for /f "delims=, tokens=1" %%i in (test.txt) do echo %%i 

# 可以提取多个,从最前面指定的%%i顺序往后取
for /f "delims=, tokens=1,2,3,4,5" %%i in (test.txt) do echo %%i %%j %%k %%l %%m

# 上面的代码可以简化如下
for /f "delims=, tokens=1-5" %%i in (test.txt) do echo %%i %%j %%k %%l %%m
for /f "delims=, tokens=1-3,4,5" %%i in (test.txt) do echo %%i %%j %%k %%l %%m

# *表示4之后的全部不分隔
for /f "delims=, tokens=1,2,3,4,*" %%i in (test.txt) do echo %%i %%j %%k %%l %%m

# 集中的路径被当作字符串处理
for /f %%a in (“C:\Documents and Settings\Administrator\桌面\note.txt”) do echo %%a

# usebackq指示集中的是文件路径
for /f "usebackq" %%a in (“C:\Documents and Settings\\note.txt”) do echo %%a

# usebackq后面集中的单引号指定是字符串
for /f "usebackq" %%a in ('C:\Documents and Settings\\note.txt') do echo %%a

# 集中的命令以``尖引号
for /f "usebackq" %i in (`dir /s /b`) do @echo %i

# 效果和上面相同,集中命令以单引号‘’
for /f  %i in ('dir /s /b') do @echo %i

# 组合提取指定文件中的内容
for /f "eol=; tokens=1,2* delims=,- " %%i in (d:\test.txt) do echo %%i %%j %%k

变量延迟

for语句只影响后面的一句代码,如果想写多句代码,必须用()。批处理解释代码时,是先读出当前行的代码并解析,for及之后的代码也是一次性加载并解释的。这就导致for之后的代码中的变量设置了并没有立即生效。如果想要立即生效,需要启用变量延迟。

  • setlocal enabledelayedexpansion启用延迟的环境变量扩展,直到出现匹配的endlocal命令,无论 setlocal命令之前的设置如何。
  • setlocal disabledelayedexpansion禁用延迟的环境变量扩展,直到出现匹配的endlocal命令,无论 setlocal命令之前的设置如何。
# 求出0100的和
@echo off
setlocal enabledelayedexpansion
for /l %%i in (0, 1, 100) do (
set /a val+=%%i
@echo !val!
)
endlocal
pause