BAT 批处理 基础语法 教程

BAT 批处理 基础语法 教程

博文地址

目录

目录目录BAT 批处理教程基础语法特点编码问题注释变量命令行参数set命令局部与全局变量环境变量判断变量是否定义字符串基本操作字符串截取替换子字符串删除子字符串if/else 语句基本语法嵌套 if 语句if errorlevelgoto 语句运算符赋值运算符算术运算符关系运算符逻辑运算符逻辑非逻辑与逻辑或数组数组元素数组元素下标为变量数组的长度在数组中创建结构函数函数定义函数的基本用法函数的返回值函数中的局部变量

BAT 批处理教程

参考:易百教程

参考:批处理之家

当Windows为我们打开了五彩缤纷的图形窗口的时候

DOS命中注定会陨落

CMD毫无悬念将萎缩

批处理逐渐趋向无声无息

而powershell的到来,无疑会让更多的人忘记批处理

这是一门即将失传的技艺

这是一块行将就木的领域

然而,命令行工具仍然具有批量处理一切的巨大威力

字符界面仍然是高效操作、方便灵活、简洁快速的代名词

基础语法

特点

批处理脚本存储在文本文件中,其中包含的命令按顺序依次执行,其功能是为了自动执行重复的命令序列

批处理文件具有特殊的扩展名BAT或CMD,可以通过双击、或在命令提示符(cmd.exe)或在开始 - 运行行中运行

批处理文件通过称为命令解释器的系统文件提供的接口(shell)来识别和执行,在Windows系统上是cmd.exe

批处理文件可以读取用户的输入,有if、for等控制结构,支持函数、数组等高级功能,支持正则表达式,可以包含其他编程代码

编码问题

在windows上,bat文件默认以GBK编码格式保存(很多开发语言、环境的默认编码为UTF-8格式),如果文件中有中文或特殊符号,强烈建议以GBK编码格式保存,否则会因各种各样的问题导致乱码进而导致执行出错!

如果不能修改文件编码格式,例如通过 for 等命令读写其他编码格式的文件,那需要使用CHCP修改编码格式。具体可用的编码参考 Code Page Identifiers

@echo off & CHCP 65001

:: 会在命令行中输出【Active code page: 65001】的提示

注释

注释有三种:

Rem 注释内容:Rem相当于命令,如果Rem的行数太多,可能会使代码变慢

:: 注释内容:建议采用这种方式的注释

%注释内容%:行内注释

@echo off

Rem Rem注释在未关闭命令回显时会在屏幕显示出来,而 :: 则什么情况下都不会显示

echo 注释方式三 %行内注释%

变量

命令行参数

可以在调用批处理文件时传递参数,%n(n为自然数)表示在调用批处理文件时传递的第n个参数:

%0 批处理文件本身,包括完整的路径和扩展名

%1 第一个参数

%9 第九个参数

%* 从第一个参数开始的所有参数

参数%0具有特殊的功能,可以调用批处理自身,以达到批处理本身循环的目的,也可以复制文件自身等等。

@echo off

echo 第一个参数为:%1

copy %0 d:\new_file.bat %最简单的复制文件自身的方法%

set命令

set [/A] varName=value

:: 仅当该值是数值类型时,才可以使用【/A】,才能正确的进行数值计算,否则会被当做字符串进行计算

:: 使用变量的时候,变量需要包含在%符号中,如【%varName%】

set message=Hello World

echo %message%

SET /A a=5

SET /A b=10

SET /A c=%a% + %b%

echo %c%

set /p用于将用户输入的内容赋值给变量,以回车表示结束

set /p a=请输入姓名:

echo 姓名为:%a%

:: 先显示指定内容(不能为空),再接受用户输入的内容,最后将用户输入的内容赋值给变量

局部与全局变量

set globalvar=默认情况下都是全局变量

SETLOCAL

set var=SETLOCAL后定义的变量只在ENDLOCAL之前有效

set globalvar=SETLOCAL后重新赋的值也只在ENDLOCAL之前有效

echo %var%

echo %globalvar%

ENDLOCAL

echo %var% %会打印:【ECHO 处于关闭状态。】%

echo %globalvar%

环境变量

echo %JAVA_HOME%

判断变量是否定义

SET /A a=5

SET str=包青天

if defined a echo 【变量a存在】

if not defined b echo 【变量b不存在】

if not [%1]==[] echo 【参数存在:%1】

if exist %1 echo 【文件 %1 存在】

字符串

基本操作

set message=字符串

echo 【%message%】

set var=3

set /A var=%var% + %var%

echo 定义为字符串变量后,还可以使用【/A】开关转换为整数:%var%

:: 上面打印内容为【6】,如果不加【/A】,那么打印结果为【3 + 3】

:: 判断字符串是否相等

if [%message%]==[字符串] echo 方式一

if %message%==字符串 echo 方式二

:: 创建一个空字符串

Set a=

if [%a%]==[] echo 检查是否为空字符串

字符串截取

其实和其他语言的规则是一致的,截取的标准格式为:

%var:~num_chars_to_skip%

%var:~num_chars_to_skip,num_chars_to_keep%

即【%var:~fromIndex,length%】

SET a=abcd

echo 【%a:~0%】【%a:~1%】【%a:~2%】【%a:~3%】【%a:~4%】

:: 【abcd】【bcd】【cd】【d】【】

echo 【%a:~-4%】【%a:~-3%】【%a:~-2%】【%a:~-1%】

:: 【abcd】【bcd】【cd】【d】-n和4-n的效果是一样的

echo 【%a:~0,0%】【%a:~0,1%】【%a:~0,2%】【%a:~0,3%】【%a:~0,4%】

:: 【】【a】【ab】【abc】【abcd】

echo 【%a:~0,-4%】【%a:~0,-3%】【%a:~0,-2%】【%a:~0,-1%】

:: 【】【a】【ab】【abc】【abcd】

echo 【%a:~1,1%】【%a:~1,2%】【%a:~2,1%】【%a:~3,1%】【%a:~3,2%】

:: 【b】【bc】【c】【d】【d】

替换子字符串

%str:new=old%

set str=包青天 白 乾涛 包青天

echo 【%str:包青=老%】【%str: =_%】

:: 【老天 白 乾涛 老天】【包青天_白__乾涛_包青天】

删除子字符串

%str:subStr=%

:: 可以认为是一种特殊的替换:将指定字符替换为空

set str=包青天 白 乾涛 包青天

echo 【%str:包青=%】【%str: =%】

:: 【天 白 乾涛 天】【包青天白乾涛包青天】

if/else 语句

基本语法

只有 if 语句时,if 语句的小括号是可选的

有 else 语句时,if 语句必须带小括号,而 else 语句的小括号是可选的

if 条件不能加小括号,否则判断条件为 false

SET /A c=5

SET str=包青天

if %c%==5 echo 只有 if 语句时,if 语句的小括号是可选的

if %str%==包青天 (

echo 如果换行的话必须加小括号,且左小括号不能换行--因为换行后就不是一条命令了,右括号不限制

REM 注意:小括号内不能有 :: 格式的注释,可以有REM格式的注释(因为REM是命令)

)

:: 【==】既可以用来判断数值型,也可以用来判断字符串

if [%1]==[] (echo 呵呵) else echo 有 else 语句时,if 语句必须带小括号,而 else 语句小括号可选

if ([%1]==[]) (echo 呵呵) else (echo if 条件不能加小括号,否则判断条件为 false)

嵌套 if 语句

if(condition1) if (condition2) do_something

:: 只有当条件1和条件2都满足时,才会执行 do_something 块中的代码

if errorlevel

环境变量 errorlevel 的初始值为0,当一些命令执行不成功,就会返回一个数值,如:1 ,2 等。

注意:IF ERRORLEVEL 是用来测试它的上一个DOS命令的返回值的,注意只是上一个命令的返回值,而且返回值必须依照从大到小次序顺序判断。

if ERRORLEVEL nubmer commend

copy %0 new_file.bat

if errorlevel 0 echo 命令成功完成

copy %0 new/file.bat

if errorlevel 1 echo 命令失败

goto 语句

@echo off & setlocal enabledelayedexpansion

SET /A a=0

:add

set /A a+=1 & echo echo a当前的值为:%a%,a+1后的值为:!a!

if %a% LSS 3 (

goto :add

) else (

goto :end

)

:end

echo 执行完毕,a的值为:!a!

运算符

赋值运算符

SET /A a=3

SET /A a+=5

echo %a%

:: 其他类似的运算还有【a-=5】【a*=5】【a/=5】【a%=5】

算术运算符

SET /A a=5

SET /A b=3

SET /A c=%a%+%b%

SET /A d=%a%-%b%

SET /A e=%b%*%a%

SET /A f=%b%/%a%

SET /A g=%a%/%b%

SET /A h=%b%%%%a%

SET /A i=%a%%%%b%

echo 【%c%】【%d%】【%e%】【%f%】【%g%】【%h%】【%i%】

:: 【8】【2】【15】【0】【1】【3】【2】

关系运算符

SET /A a=5

SET /A b=10

if %a% EQU %b% echo 相等

if %a% NEQ %b% echo 不相等性

if %a% LSS %b% echo 左小于右

if %a% LEQ %b% echo 左小于等于右

if %a% GTR %b% echo 左大于右

if %a% GEQ %b% echo 左大于等于右

逻辑运算符

批处理语言配备了一整套布尔逻辑运算符,如AND,OR,XOR,但只适用于二进制数字

对于TRUE或FALSE也没有任何值

可用于条件的唯一逻辑运算符是NOT运算符

为非二进制数字实现AND/OR运算符的方法是使用嵌套的IF条件或goto语句

逻辑非

SET /A a=5

IF NOT %a%==6 echo 逻辑非运算符NOT的使用

逻辑与

借助 if 语句实现

SET /A a=5

if %a% LSS 6 (

if %a% GTR 4 (

echo 嵌套if实现and的功能

)

)

if %a% LSS 6 if %a% GTR 4 echo 嵌套if实现and的功能

借助 goto 语句实现

SET /A a=5

if not %a% LSS 6 goto end

if not %a% GTR 4 goto end

:: 为了保持和上面if的结构一致,上面是用了两个not,实际肯定是可以不用not的

goto and_function

:and_function

echo 嵌套if实现and的功能

:end

echo end

逻辑或

逻辑或实现起来比逻辑与还要复杂一些,一般都需要借助 goto 语句来实现!

不借助 goto 语句实现的情况

这种方式只适合满足条件时要执行的命令比较少的场景,否则会有大量的冗余代码

SET /A a=3

IF %a% LSS 4 (

echo 如果满足条件一,则执行n条命令

) else IF %a% GTR 6 (

echo 否则,如果满足条件二,也会执行相同的n条命令

)

IF %a% LSS 4 (echo 满足条件) else IF %a% GTR 6 (echo 满足条件)

借助 goto 语句实现

SET /A a=5

IF %a% LSS 4 goto or_function

IF %a% GTR 6 goto or_function

goto end

:or_function

echo 嵌套if实现or的功能

:end

echo end

数组

数组类型并没有明确定义为批处理脚本中的类型,但可以模拟出来,但是有些功能使用起来会有诸多限制。

白哥说:其实批处理脚本中的数组就是多个名称类似的变量,其本身没有任何特性或语法,只不过因为这些变量的格式比较像C、Java中的数组,而数组又是那么深入人心,所以我们将其当做数组来看待了而已。

数组元素

其实就是一系列相互之间没任何关系的变量!

set a[0]=10

set a[1]=1

set a[1]=11

set a[3]=14

echo 【%a[0]%】【%a[1]%】【%a[2]%】【%a[3]%】【%a[4]%】

:: 【10】【11】【值不确定】【14】【值不确定】

:: 数组中的每个元素都需要使用set命令专门定义

:: 注意,未定义的元素的值是无法确定的,并不一定是没有值(虽然大部分情况都是没有defined、也没有值的)!

数组元素下标为变量

数组元素下标为变量时,可以认为是:一个变量的名称取决于另一个变量!

set a[0]=10

set /a k=0

:: 以下3种方式均可正确访问 a[k]

echo %k%-%a[0]%

call echo %k%-%%a[%k%]%%

setlocal enabledelayedexpansion & echo %k%-!a[%k%]!

:: 因为a[%k%]之前并没有定义(仅仅是定义了a[0]),所以必须`设置本地为延迟扩展`才能正常访问,且访问时必须使用!代替%

数组的长度

没有直接的函数来确定数组中元素的数量,只能通过遍历数组中的值列表手动计算。

set d[0]=10

set d[1]=11

set x=0

:getArrayLength

if defined d[%x%] (

call echo %x%-%%d[%x%]%%

set /a x+=1

goto :getArrayLength

)

echo 数组长度为 %x%

:: 注意,如果数组元素定义时不连续,这种方法计算出来的值可能就是错误的,核心在于上面的【defined】表达式

在数组中创建结构

set obj[0].Name=包青天

set obj[0].ID=66

set cur.Name=%obj[0].Name%

echo 【%obj[0]%】【%obj[0].Name%】【%cur.Name%】【%cur.ID%】

:: 【】【包青天】【包青天】【11】 cur.ID的值没有定义,所以打印结果是不确定的

函数

函数定义

定义函数的格式

:function_name

Do_something

EXIT /B 0

:: EXIT语句用于确保函数正常退出

调用函数的格式

Call :function_name parameter1, parameter2… parametern

:: 需要确保在主程序中放入【EXIT /B %ERRORLEVEL%】语句,以便将主程序的代码与函数分开

函数的基本用法

可以通过使用%~n(n代表参数的位置),来在函数内部访问参数

亲测,完全可以省略掉其中的~符号

set p=包青天

CALL :function_1

CALL :function_2 a p %p%

EXIT /B %ERRORLEVEL%

:function_1

echo 调用了【%0】函数

EXIT /B 0

:function_2

echo 调用了【%0】函数,参数为【%~1】【%2】【%3】,所有参数为【%*】

EXIT /B 0

函数的返回值

函数可以通过简单地传递变量名称来处理返回值,这些变量名称将在调用该函数时保存返回值

CALL :function_3 c & echo 一行代码时必须使用延迟变量【!c!】【%c%】

CALL :function_3 d

echo 不是一行代码时两种方式都可以【!d!】【%d%】

set p=包青天

CALL :function_3 %p% & echo 在函数中修改变量的值时,参数不是传入变量的引用【!p!】【%p%】

CALL :function_3 p & echo 而是传入变量的名称【!p!】【%p%】

EXIT /B %ERRORLEVEL%

:function_3

if NOT [%1]==[] set %1=baiqiantao

EXIT /B 0

参数作为输出参数时,此文件不要设置 setlocal enabledelayedexpansion,且函数内不要使用SETLOCAL、ENDLOCAL

函数中的局部变量

函数中的局部变量可以用来避免名称冲突,并保持函数本地的变量变化

调用SETLOCAL命令后可确保命令处理器对所有环境变量进行备份,并可在调用ENDLOCAL命令后恢复

当到达批处理文件结束时,即通过调用GOTO:EOF,ENDLOCAL被自动调用

使用SETLOCAL对变量进行本地化允许在函数中自由使用变量名称,而不必担心与函数外使用的变量名称冲突

可以递归地调用一个函数,使用SETLOCAL可以确保每个级别的递归都使用自己的一组变量,即使变量名被重用

set x=Outer

set y=Outer

CALL :function_1 x y & echo 【!x!-!y!】--【%x%-%y%】

CALL :function_2 x y & echo 【!x!-!y!】--【%x%-%y%】

EXIT /B %ERRORLEVEL%

:function_1

set x=Inner1

set %2=Inner1

:: 当没有SETLOCAL时,以上两种set方式都能改变函数外的变量的值

EXIT /B 0

:function_2

SETLOCAL

set x=Inner2

set %2=Inner2

:: 当有SETLOCAL时,函数内部对变量的修改不影响函数外部的变量的值

ENDLOCAL

EXIT /B 0

2019-12-30

相关推荐

开网店找货源的十种方法
二十八星宿之一:氐宿人命運解說
农业银行卡BIN 622843

农业银行卡BIN 622843

07-10 👁️ 2504
经常被玩家误解的梦幻西游转区规则,至今仍然有人搞不清楚
为什么游戏界的最高奖项获得者大部分都是买断制?
宁波22个免费景点大全!不花一分钱玩遍宁波
懂行的人建议买苹果还是小米?2025年终极选购指南,看完不再纠结
为什么有钱人喜欢“装穷”?揭秘背后的真相!
车辆管理软件哪个好用?好用的车辆管理软件盘点