参考:https://www.cnblogs.com/siwuxie095/category/925785.html
- 批处理(Batch):望文知义,对某对象进行批量处理,是windows中的一种脚本。
- .bat和.cmd的文件都是批处理文件,只是前者更常见。
第一个批处理文件:保存到桌面位.bat或.cmd格式文件,双击运行
运行结果为:
@作用就是关闭当前命令行回显,无论echo是否为打开状态,在执行窗口中都不显示它后面当前行命令本身
参数说明:
echo on -----打开回显,一般系统默认就是echo on,只有当执行过echo off后才用
echo off -----关闭回显,关闭除当前行的后面处理命令的回显,只显示执行后的结果。
echo+空格 ----查询当前计算机回显状态,on or off
echo+信息 ------显示信息,注意echo后要紧跟一个空格或特殊字符(空格和特殊字符不会显示)
echo.------显示空行,相当于回车
Rem和 ::
这连个都是用作批处理注释,写的时候写在被注释的代码上一行
二者的异同:
同:都是注释命令,在批处理脚本中,rem和::命令等效,在执行时不显示,也不起任何的作用,只是为了增强代码的可读性
异:关闭回显时,rem和::后的内容都不会显示,但当打开回显时,rem后的内容会显示, ::后的内容依然不会显示
Goto--无条件跳转命令,标签必须单独一行,且以冒号开头,程序运行到goto,将自动跳转到:定义的部分去执行。
例:goto和if组合实现循环
跳转高级技巧:
用call实现跳转 如:
Set /a 指定等号右边的字符串被评估为数字表达式,用于执行算数运算
Set /p 获取通过键盘输入的值
Goto和call跳转的区别:
1.格式:goto 后面的标签前有无冒号均可,call 后面的标签前必须有冒号
2、执行顺序:goto 跳转到目标程序段后,就顺序执行下去,直到程序执行完毕 ,并且不会回到原来的地方, call 跳转到目标程序段后,会将目标程序段执行完,然后回到call原来的地方,然后继续执行下去,直到程序执行完毕
3.call调用程序段还可以传参数,goto不能
如 demo.bat: test.bat:
Demo.bat执行结果: test.bat执行结果:
Start:启动另一个窗口运行指定的程序或命令,批处理程序继续往下执行,不理会外部程序的运行情况
例:
执行结果:
注意事项:
当打开带有空格的路径,就必须用双引号将路径括起来,而在start命令中双引号却又代表着设置标题,如果对路径添加双引号,程序会认为是设置标题,程序依然无法启动
解决方法:
在start后面多添加一对空双引号,这样程序会认为第一个双引号的内容为标题,第二个双引号的内容为路径,即可正确执行
Shift:--更改批处理文件中可替换参数的位置
语法:Shift [/n]
如果命令扩展被调用,shift命令支持 /n命令行开关;该命令行开关告诉我们从第n个参数开始移位;n介于零和八之间
举例说明:数据求和
运行结果:
这里面%0-%9依次代表:
%0 |
%1 |
%2 |
%3 |
%4 |
%5 |
%6 |
%7 |
%8 |
%9 |
无 |
:sub |
sum |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
%0代表自身,具体到这里就是:sub,而%1代表的是sum,这里的初始值是0,shift /2 即将%3移位到%2,%4移位到%3.......
查看第二个参数值变化:
If语法格式:
①比对结果:IF [NOT] string1==string2 do command
注意:1).比对字符串时,大小也会严格比对,用 “/i”开关忽略大小写,才会认为”A=a”
2).string1或者string2中任何一个字符串出现空格,比较不能继续,程序自动退 出,为了避免这种情况采用加双引号形式,包含空格在内的整个字符串的比对, 及空格也会当成符号来比对。
②存在判断:IF [NOT] EXIST filename do command
例:
结果为:
- . IF DEFINED variable command --用来判断变量是否存在,如果变量已定义或 存在,就执行command
例: 执行结果:
注意:左括号必须和if同行,右括号必须和else同行,
word和后面的等号 = 之间不能有空格,否则不能成功
%0不是返回参数,其有两层意思:
第一层:如果%0前有echo等命令,则代表返回该批处理所在的绝对路径
第二层:如果%0前没有任何参数,则代表自身批处理,会无限循环执行
Set命令:
- 用set命令赋值自定义变量
标准格式:
SET [variable=[string]]
注意:1)等号左边不允许有空格,否则出错,等号右边全部都会赋值到variable
变量,包括空格。
- 批处理对变量名的大小写不敏感。但对变量值的大小写敏感
- 用set命令读入并赋值到自定义变量
格式:
SET /P variable=[promptString]
/P 命令行开关允许将变量数值设成用户输入的一行
- 用set实现计算
语法:
SET /A expression
/A命令行开关指定等号右边的字符串为待计算的数字表达式。也就是让set可以支持数学符号进行运算。所有需要计算的表达式都必须添加开关 /a
3.1)、将接受的参数赋给一个变量
@ECHO OFF
Rem 开启延迟变量
setlocal enabledelayedexpansion
set "ipath="
echo %1
rem 给变量赋值的时候最好用引号把变量括起来,因为bat对空格异常敏感
set "ipath=%1"
echo !ipath!
echo %2
测试结果:
- 字符串的截取:
%a:~[m[,n]]%
方括号表示可选,%为变量标识符,a为变量名,冒号用于分割变量名和说明部分, ~可简单理解为”偏移量”即可,m和n可以取正数,也可取负数,表不同含义
关于%a:~[m[,n]]中m n取值的含义:
M正或0,n正 |
舍弃变量a的前m位,后再取其n位 |
M正或0,n负 |
舍弃变量a的前m位和舍弃末尾的n位后剩下的值 |
M正或0,n缺省 |
舍弃变量前m位后,去剩下的所有值 |
M负,n正 |
取变量a的末尾m位,后再取前n位 |
M负,n负 |
取变量a的末尾m位,后舍弃末尾的n尾喉剩下的值 |
M负,n缺省 |
取变量末尾m位 |
注意:n值可以缺省,但不可以位0。m可以为任意值
Set技巧高级篇:
如果输出大量的数据,用echo命令,每行只输出一个数据,这样会浪费大量的显示界面,不符合习惯,将大量数据在同一行输出必须使用set命令
Set /p var=%num%<nul,可以实现对数字连续的效果
例:
结果:
上面的全部数据都揉成一团,不符合习惯,可以增加空格隔开数据:
运行结果为:
实现上下对齐,需要借助输出格式: %var:~m,n%
具体实现:先对每个数字前面增加若干个空格,然后用%var:~m,n%取末尾k位输出即可,另外加一个计数器,每输出i尾后换行
格式:
Set var=%str%
Set /p print=%var:~-k%<nul
例:读入两个数据,输入两个数据之间所有数,要求每行输出10个数据后换行,并且上下数字要靠右对齐
Goto方法实现:
运行结果:
For循环实现:
小结:
<nul 是0<nul 的简写,0句柄是默认的输入句柄,nul是空设备所以 <nul 表示从空设备获取输入。
Set /p 执行时会等待用户输入,<nul使得set /p 输入设备为空,此时set /p 就会自动终止输入,此处的<nul和手动按回车效果一样,只是他不需要人工操作。
查看操作系统的名称:
Win+R,输入dxdiag,回车
For循环:
对每一组文件中的每一个文件执行某个特定命令
标准格式: FOR %%variable IN (set) DO command [command-parameters]
更详细的语法:
FOR [-d | -r | -l | -f] %%variable IN (set) DO command [command-parameters]
中文翻译:
FOR [-d | -r | -r | -f] %%变量名IN (相关命令) DO [执行命令]
这里用%%,两个百分号是批处理文本中书写的格式,如果是用户在命令行输入的形式,只需要一个%号
参数详解:
For没有任何开关的情况:
For %%i in (*) do echo %%i
这条命令的变量%%i取值*,而不是取具体的值,表示特殊含义,即显示当前目录下,所有非文件夹的文件名字
例:
显然:空格、逗号、和分号、都可以作为分隔符,一般情况下都用逗号做分割符
/d
只搜索当前目录下的目录(也就是文件夹,不包括子目录),也无法搜索到隐藏的文件夹
语法:
For /d %%variable in (set) do command [command-parameters]
搜索set(可以包含通配符*和?)里面的文件夹后执行指定Command。用于目录搜索,不会用于搜索文件
通配符*和?的区别:
*表示任意n个字符用一个*符号足以。而?表示任意一个字符,当要表达“不多于k个字符的文件夹”,就要写k个?,对于文件夹命名的中文(任意一个),算0个字符
/r
只搜索目录中(包括子目录和子目录的子目录,也就是目录树)的所有文件,这个和/d作用互补
语法格式:
FOR /R [[driver:]path] %%variable IN (set) DO command [command-parameters]
如果在/r 后没有指定目录,则使用当前目录,如果set仅为一个单点(.)字符,则枚举该目录树
注意:在循环里,不能改变循环变量的值!对循环上下限变量允许计算。但不会影响循环次数
/F
N能够对字符串进行操作,也能够对命令的返回值进行操作,还可以访问硬盘上的ASCII码文件,常用于文本信息编辑,如查询、提取、替换等
格式:
FOR /F [“options”] %%variable IN (file-set) DO command [xommand-parameters] 文件名
file-set 不用引号(如果文件名含有空格时,就需要借助usebackq了)
FOR /F [“OPTIONS”] %%variable IN (“string”) DO command [command-parameters] 字符串
String要用字符串
FOR /F [“OPTION”] %%variable IN (‘command’) DO command [command-paraneters] 命令
Command要用单引号
注意:带引号的字符串“options”包括一个或多个指定不同解析选项的关键字:
eol=c、skip=n、delims=xxx、tokens=x,y,m-n、usebackq
解析选项关键字详解:
- eol=c 忽略(隐藏、屏蔽)所有以字符是c开头的行
格式:
FOR /R “eol=c” %%I IN (Command1) DO Command2
一、eol=
默认情况下屏蔽冒号开头的行(无论是中文冒号还是英文冒号,都会屏蔽掉)
但冒号本身不会被屏蔽,还是会被显示出来
注意:这里被处理的文本里的冒号和后面的文字字符都必须有空格隔开,
否则无法对文本进行屏蔽
二、Skip=n忽略文本的前N行的内容。(N必须大于0,不能等于0)
格式:
FOR /F “skip=n” %%i IN (Command1) DO Command2
- delims=xxx (xxx是被定义的符号,该符号在文本中存在,将作为分隔符)
格式:
FOR /F “Delims” %%i IN (Command) DO COmmand2
例: 代码:
结果:因为没有定义要显示的列,这里默认只显示第一列的内容,,默认情况下忽略第一个分隔符(冒号)及其后面的内容
- tokens=x,y,m-n
Tokens=x 只显示第x列 |
Tokens=x,y,z只显示x,y,z列 |
Tokens=m-n只显示从m列到n列(m<n) |
Tokens=*显示文本中的所有内容(此时,不管有没有用delims定义分隔符或定义了多少分隔符,文本的所有内容包括所有符号都会被显示出来) |
注意:
在没有delim进行分割,而带有空格的行,空格后面的内容被忽略了,原因就是在默认情况下,及时没有用delims选项,for也会以空格作为分隔符,将空格后的内容屏蔽掉。
五、Usebackq
1)、当集合中的文件名file-set含有空格时,使用双引号来保持文件名或路径的完整性, 并且在参数后打开”usebackq”
语法:
FOR /F “usebackq” %%I IN (“FileNameSet”) DO Command2
2)、当使用usebackq处理文字字符串时,使用单引号
格式:
FOR /F “usebackq” %%variable IN (‘command’) DO command [command-parameters]
3)、当集合内是可执行的命令式。使用后引号(Esc键下的那个键)
语法:
FOR /F “usebackq” %%variable IN (`command`) DO [command-paramters]
六、for实际运用样例:
For %%i in (*) do echo %%i
显示当前目录下,所有非文件夹的文件名(.rar .jpg .exe .bat .sys等等所有非文件夹)
For %%i in (*.*) do echo %%i
搜索当前目录下的所有文件
for /d %%i in (*) do echo %%i
搜索当前路径下所有文件及的名字
For /d %%i in (C:\windows\w???) do echo %%i
搜索C:\文件夹里,所有以w开头的,名字不超过4个字符的文件夹
For /r c:\ %%i in (*.exe) do echo %%i
搜索C盘下包括子目录的所有exe文件
For /r %%i in (*.txt) do @echo %%i
搜索当前路径目录树的所有txt文件
For中的变量:
For 变量参照的替换已被增强,您对现在可以使用下列选项语法:
~I -删除任何引号(“),扩充%I 注意:单引号不会被删除
注意这个I是个0到9数字
%~fI-将%I扩zh充到一个完全合格的路径名
%~dI-仅将%I扩充到一个合格的驱动号
%~pI-仅将%I扩充到一个路径
%~nI-仅将%I扩充到一个文件名
%~xI-仅将%I扩充到一个文件扩展名
%~sI-扩充的路径只含有短名
%~aI-仅将%I扩充到文件的文件属性
%~tI-仅将%I扩充到文件的日期/时间
%~zI-将%I扩充到文件的大小
%~$PATH:I-查找列在路径环境变量的目录,将%I扩充到找到第一个完全合格的名称,如果环境变量名未被定义或者没有找到文件。此组合键扩充到空字符串
可以组合修饰符来得到多重结果:
%~-dpI-仅将%I扩充到一个驱动器号和路径
%~nxI-仅将%I扩充到一个文件名和扩展名
%~fsI-仅将%I扩充到一个带有短名的完整路径名 注意:只含有短名zhihanyo
%~dp$PATH:i-查找列在路径环境变量的目录,并将%I扩充到找到的第一个驱动号和路径
%~ftzaI-将%I扩充到类似输出路线的DIR
举例说明:
同目录批处理:
运行结果:
可见删除规则:
- 若字符串首尾同时存在引号,则删除首尾引号
- 若字符串尾不存在引号,则删除字符串首的引号
- 如果字符串中间存在引号,或者只有尾部存在引号,则不删除
总结:无头不删,有头连尾删,有头无尾只删头
列:如果指明搜索路径:
程序不能正确执行,无论对搜索的格式如何修改,出现这种问题的原因是因为:
%~aI
%~tI
%~zI
需要指明完整路径,而dir搜索出的只是文件名 ,这样%%~tI就会把当前工作目录设置为文件路径,所以找不到文件。
用pushd来转到相应目录即可:也可以用cd /d 来指明:
最后一个,%~$path:I非常特殊:
还是不能正确执行。
如果改为:
运行结果:
再如:
运行结果为:
For拾遗:
- for语句例,do后面一般有括号,有括号就是符合语句,假如需要用到括号中的变量,就需要使用延迟变量。
- For语句里不能改变循环变量%%i的值
- For语句里,可以改变上下限的值,但不会影响循环次数
- For语句里以%var:~m,n%形式截取字符,会变得掣肘!
原因是for语句里不能对循环变量%%i进行预运算,以及在延迟变量环境下,很难表达%var:~m,n%
一个列子:输入一串字符,要求从字符串末尾一个一个字符输出到字符串的开头
@echo off
setlocal enabledelayedexpansion
set var=abcdefghijklmnopqrstuvwxyz
for /l %%i in (-1,-1,-26) do (
set tem=!var:~%%i!
set tem=!tem!
set tem=!tem:~1,1!
echo !tem!
)
Pause
运行结果:
批处理中Copy与Xcopy的区别
1):copy不能在有子目录存在的文件中拷贝文件的同时重命名此文件名(注:这里C:为根目录,bat为子目录),而xcopy能,不过会出现提示,当然你可以加参数而不使它提示。
C:\>copy c:\bat\hai.bat d:\bat\hello.bat
提示:系统找不到指定的路径。
已复制 0 个文件。
但你可以用
C:\>copy c:\hai.bat d:\hell.bat
已复制 1 个文件
C:\>xcopy c:\bat\hai.bat d:\bat\hello.bat
目标 D:\bat\hello.bat 是文件名
还是目录名
(F = 文件,D = 目录)? f
C:\bat\hai.bat
复制了 1 个文件
2):copy命令能合并两个文件,而xcopy不能
将文件1.txt和2.txt合并为3.txt
copy /b c:\1.txt+2.txt c:\3.txt
命令格式:copy /b 文件1+文件2+......文件N 合并后的文件名
命令讲解:使用“+”将多个相同或不同格式的文件合并为一个文件。
小提示:
1.在尾部隐藏了文本数据的图片文件,在使用了其他文件编辑器并保存后,隐藏的文本数据有可能丢失。
2.MP3文件在使用此方法连接后,就可以实现连续播放。
3.合成图片/歌曲这样的二进制文件必须使用/b参数(b代表Binaty,二进制),否则将会失败;另一个合并参数是/a(ASCII,文本文件),只能用于纯文本的合并。两参数不能同时使用,二进制方式可以合并文本文件和二进制文件,而文本方式用于纯文本的合并。
3):C:\>copy c:\bat\hai d:\hello
命令解释:将C盘bat目录下所有文件复制到D盘hello目录下。你如果要选择指定定类型的文件(如txt文件)到D:\hello下的,则可以用C:\>copy c:\bat\hai\*.txt d:\hello
注:不会复制子目录下的文件及文件夹。D盘hello目录必须存在
C:\>xcopy c:\bat\hai d:\hello /e/h
命令解释:将C盘bat文件夹拷进D盘hello文件夹,包括所有子目录及具有隐藏和系统文件属性的文件。无论hello文件夹是否已经存在,如果不存在的话系统会提示你创建。
注:/e表示复制所有子目录,包括空目录。/h复制具有隐藏和系统文件属性的文件。
copy命令用法:
E:\Work\Project_Experience\bat_script>copy /?
将一份或多份文件复制到另一个位置。
COPY [/D] [/V] [/N] [/Y | /-Y] [/Z] [/L] [/A | /B ] source [/A | /B]
[+ source [/A | /B] [+ ...]] [destination [/A | /B]]
source 指定要复制的文件。
/A 表示一个 ASCII 文本文件。
/B 表示一个二进位文件。
/D 允许解密要创建的目标文件
destination 为新文件指定目录和/或文件名。
/V 验证新文件写入是否正确。
/N 复制带有非 8dot3 名称的文件时,
尽可能使用短文件名。
/Y 不使用确认是否要覆盖现有目标文件
的提示。
/-Y 使用确认是否要覆盖现有目标文件
的提示。
/Z 用可重新启动模式复制已联网的文件。
/L 如果源是符号链接,请将链接复制
到目标而不是源链接指向的实际文件。
命令行开关 /Y 可以在 COPYCMD 环境变量中预先设定。
这可能会被命令行上的 /-Y 替代。除非 COPY
命令是在一个批处理脚本中执行的,默认值应为
在覆盖时进行提示。
要附加文件,请为目标指定一个文件,为源指定
数个文件(用通配符或 file1+file2+file3 格式)。
xcopy命令用法:
E:\Work\Project_Experience\bat_script>xcopy /?
复制文件和目录树。
XCOPY source [destination] [/A | /M] [/D[:date]] [/P] [/S [/E]] [/V] [/W]
[/C] [/I] [/Q] [/F] [/L] [/G] [/H] [/R] [/T] [/
[/K] [/N] [/O] [/X] [/Y] [/-Y] [/Z] [/B]
[/EXCLUDE:file1[+file2][+file3]...]
source 指定要复制的文件。
destination 指定新文件的位置和/或名称。
/A 仅复制有存档属性集的文件,但不更改属性。
/M 仅复制有存档属性集的文件,并关闭存档属性。
/D:m-d-y 复制在指定日期或指定日期以后更改的文件。
如果没有提供日期,只复制那些源时间比目标时间新的文件。
/EXCLUDE:file1[+file2][+file3]...
指定含有字符串的文件列表。每个字符串在文件中应位于单独的一行
如果任何字符串与复制文件的绝对路径的任何部分相符,则排除复制
该文件。例如,指定如 \obj\ 或 .obj 的字符串会分别排除目录
obj 下面的所有文件或带有 .obj 扩展名的所有文件。
/P 创建每个目标文件之前提示您。
/S 复制目录和子目录,不包括空目录。
/E 复制目录和子目录,包括空目录。与 /S /E 相同。可以用来修改 /
/V 验证每个新文件的大小。
/W 提示您在复制前按键。
/C 即使有错误,也继续复制。
/I 如果目标不存在,且要复制多个文件,则假定目标必须是目录。
/Q 复制时不显示文件名。
/F 复制时显示完整的源文件名和目标文件名。
/L 显示要复制的文件。
/G 允许将加密文件复制到不支持加密的目标。
/H 也复制隐藏文件和系统文件。
/R 覆盖只读文件。
/T 创建目录结构,但不复制文件。不包括空目录或子目录。/T /E 包括
空目录和子目录。
/U 只复制已经存在于目标中的文件。
/K 复制属性。一般的 Xcopy 会重设只读属性。
/N 用生成的短名称复制。
/O 复制文件所有权和 ACL 信息。
/X 复制文件审核设置(隐含 /O)。
/Y 取消提示以确认要覆盖现有目标文件。
/-Y 要提示以确认要覆盖现有目标文件。
/Z 在可重新启动模式下复制网络文件。
/B 复制符号链接本身与链接目标相对。
/J 复制时不使用缓冲的 I/O。推荐复制大文件时使用。
开关 /Y 可以预先在 COPYCMD 环境变量中设置。
这可能被命令行上的 /-Y 覆盖。