bat中if语句的用法

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/sanqima/article/details/37818115


   例如,删除“C:\Documents and Settings\Administrator\桌面\T1\txt\批处理实验\unit1”里的a.txt文件,使用if的代码如下:

@echo off
if exist "C:\Documents and Settings\Administrator\桌面\T1\txt\批处理实验\unit1\a.txt" (
  echo file is find!
del "C:\Documents and Settings\Administrator\桌面\T1\txt\批处理实验\unit1\a.txt"
) else (
  echo file is not found!
)
pause>nul 

2.if——条件判断(分支)语句
   “if”语句是批处理中的条件分支语句,表示的意思就是“如果...则...否则...”,大多用在批处理程序中的条件处理部分。“if”语句在批处理中使用的是比较广泛的,例如要查看某个文件,则首先要确定该文件存在才可以查看,否则MS-DOS会抛出错误信息,这个时候就可以使用“if”语句进行判断。“if”命令语句是通过条件成立与否来决定语句的执行,这里的条件成立和条件不成立可以理解为“true”和“false”,但是批处理中不存在这两个常量。“if”语句所表达的意思是只有当条件成立时才会执行指定的命令语句,主要有以下几种用法。
1.判断信息是否相等(“==”)
   “if”命令语句就是用于条件的判断,然而由于批处理脚本本身比较弱化,所以初始的MS-DOS只能支持信息相等的比较,也就是只支持“==”操作符。用于比较字符串与字符串、变量与变量、变量与字符串之间是否相等,如果相等则表示条件成立。用法如下:
if [not] 信息比较表达式 (
   命令行1
) else (
   命令行2
)
这里的“信息比较表达式”的格式为“字符串1==字符串2”或“变量1==变量2”或“变量==字符串”的形式,也即是说只能使用“==”进行字符串或变量之间的比较,上面的“not”表示相反操作,不做多的解释,来看下面的例子:

@echo off
if abc==ABC (
   echo abc euqal ABC
) else (
   echo abc not euqal ABC
)
pause>nul

 

 

保存为批处理文件,执行既可以看到效果,可以自行修改,添加“not”试试。
2.判断错误级别信息
   错误级别“errorlevel”是MS-DOS的内置环境变量,在上面已经介绍过,主要用于保存上一条命令语句是否执行成功,成功则返回0,失败或错误则返回相对应的错误级别码。然而“errorlevel”是内置环境变量,所以可以使用下面的方式判断:

 

@echo off
if %errorlevel%==0 (
  echo success!
) else (
  echo failed!
)
pause>nul
然而“if”语句提供了一种特殊的错误级别判断方式,如下:
if [not] errorlevel number (
   命令行1
) else (
   命令行2
)

 


这种方式并不是使用变量的方式进行引用,而是作为关键字使用,“number”表示一个错误级别码,“not”表示相反操作,不做多的解释。使用这种方式比较简洁。
3.判断文件是否存在
   在上面已经提到关于文件是否存在的判断,“if”语句提供了一种特殊的文件判断方案,用法如下:
if [not] exist filepath (
   命令行1
) else (
   命令行2
)
其中“exist”是关键字表示“存在”,“filepath”表示要判断的文件路径,如果检查到指定的文件存在则执行对应的命令块,“not”表示相反操作,不做多的解释。多说无益,直接看例子:

@echo off
if exist C:\a.txt (
  echo file is find!
del C:\a.txt
) else (
  echo file is not found!
)
pause>nul

 


上面的例子表示如果检查到C盘存在“a.txt”文件则删除该文件,保存为批处理文件试试即可。
4.判断MS-DOS扩展版本号(扩展用法)
   MS-DOS扩展版本号“cmdextversion”是MS-DOS的内置环境变量,在上面已经介绍过,当在使用某个新扩展特征时可以首先判断版本号是否对应,不过该用法需要在启用命令扩展之后才能使用,而命令扩展默认是启用的,进行扩展版本号判断是“if”语句的扩展用法。用法如下:
if cmdextversion number (
   命令行1
) else (
   命令行2
)
意思是说当当前批处理扩展版本号与给定的“number”值对应时执行“语句1”否则执行“语句2”,大多数情况下不会使用这个命令语句。
5.判断变量是否存在(扩展用法)
   变量是否存在的检查是“if”语句的扩展用法,用法比较广,可以判断变量是否被声明,然后在斟酌使用,不过该用法需要在启用命令扩展之后才能使用,而命令扩展默认是启用的,用法比较类似文件是否存在的判断用法,如下:
if defined 变量名 (
   命令行1
) else (
   命令行2
)
当变量被声明定义后“defined 变量名”才会成立,否则不会成立,具体实例可以自行编写。
6.信息比较运算(扩展用法)
   上面介绍过“if”默认情况下只支持相等比较运算,然后后续考虑则对“if”语句进行了命令扩展,使其可以支持多种比较运算操作,不过该用法需要在启用命令扩展之后才能使用,而命令扩展默认是启用的。用法与“if”相等比较运算的用法一致,如下:
if [/i] 操作数1 比较运算符 操作数2 (
   命令行1
) else (
   命令行2
)
其中操作数可以是字符串也可以是数值,同时还可以是变量;“/I”选项用于开启比较过程中字符串大小写忽略功能;在命令扩展下支持的比较运算符有:“equ(等于)”、“neq(不等于)”、“lss(小于)”、“leq(小于等于)”、“gtr(大于)”、“geq(大于等于)”六种,其中“lss”、“leq”、“gtr”和“geq”四种比较操作符主要用于对数值进行比较,当参与比较的字符串是字符串时,将被转换为对于的ASCII码进行比较;而“equ”和“neq”既可以比较数值也可以比较字符串。来看下面的例子:

@echo off
set var1=123
set var2=abc
set var3=12
if /i %var2% equ ABC (
  if %var1% geq %var3% (
    echo %var1%^>=%var3%
  ) else (
    echo %var1%^<%var3%
  )
) else (
  echo %var2%不等于ABC
)
pause>nul

 


上面的例子可以说明“/I”的用法,以及其他命令扩展下的操作符用法,保存为批处理文件即可执行查看效果。
   综上所述,特别提示以上的“if”语句中的“else”子句是可省略的,“else”只是起到多分支的作用,表示当条件不成立时执行的处理过程,不必要时可以去掉。关于“()”表示范围,用于表示多条语句执行的语句块(批处理中的每一条语句都是以换行符作为结束符号的),也就是说当条件成立是会执行“if”后“()”内的所有语句,当只有一条语句需要执行时可以省略“()”,特别需要注意的是省略“()”时,命令和“if”语句必须写在一行,当有“else”子句时必须使用“()”。【小提示:注意“()”与关键字之间的空格】
3.setlocal/endlocal——启动/结束延迟环境变量扩展功能
   前面已经介绍过变量的引用原理,就是查找变量名对应的值来替换“%变量名%”字符串,从而达到变量引用的效果,这个过程也称之为变量扩展过程,这种过程可用于处理基础的普通的变量,然而我们来看看下面的例子:

@echo off
set var=before
if "%var%" == "before" (
  set var=after
  if "%var%" == "after" (
    echo 重置var的值成功[var=%var%]
  ) else (
    echo 重置var的值失败[var=%var%]
  )
)
echo var=%var%
pause>nul

 

 

按照正常的执行流程可以推断出结果为“重置var的值成功[var=after]”,然而真实执行的结果并不是我们想象的,保存为批处理文件并执行输出的结果为“重置var的值失败[var=before]”。我们来看看为什么为出现这种情况?首先声明了变量var的值为before,紧接着为一个“if”语句,又在“if”语句中对变量var进行重新赋值,然后在进行判断,然而该程序在解释执行的过程中,将“if”语句以及其内的“set”命令和“if”语句作为一整条语句进行解释的,当遇到“%var%”时会自动查找“var”的值替换当前语句,也就是整个外层“if”语句中的所有“%var%”字符串,因此内部的“if”判断条件中的“%var%”被替换成了“before”,所以永远都不会与“after”相等。这就是变量扩展的过程,那么外层“if”语句中的“set var=after”是否执行了呢?答案是肯定的,通过在程序末尾追加“echo var=%var%”可以看出。
   通过上面的例子,可以得出一个结论就是批处理中的默认变量替换过程值针对一整条语句的,也就是说如果一整条语句中某个地方有变量的引用,则将会影响到该条语句中的所有变量引用,同一条语句中的所有变量引用会在同一时刻被替换为该变量对应的值。通俗的说,就是默认情况下,一条语句中的变量的值是固定的。
   针对这个现象,批处理提出了延迟环境变量(简称延迟变量)的概念,主要用于对变量进行扩展,弥补普通变量的应用过程中的不足,通过延迟环境变量可以实现在一整条语句中改变变量的值。也就是说可以通过延迟环境变量概念来实现子句内部的变量声明、定义和赋值等操作。批处理中给出了“setlocal”和“endlocal”命令来实现延迟变量扩展功能的开启和关闭操作,来看看两个命令的用法:
setlocal enableExtensions | disableExtensions
setlocal enableDelayedExpansion | disableDelayedExpansion
endlocal
“setlocal”命令有两种用法,第一种用法用于启动(enableExtensions)或者停用(disableExtensions)命令处理器扩展名功能,这个用法主要用于管理MS-DOS解释器的命令扩展功能,默认是开启的,一般很少用到;第二种用法就是现在介绍的用于启动(enableDelayedExpansion)或者停用(disableDelayedExpansion)延迟环境变量扩展功能,默认是停用的。“endlocal”命令用法比较简单,就一个单一的命令行,该命令行主要用于停用延迟环境变量扩展功能,命令执行后将会还原当前批处理的扩展功能为默认值,所做的环境变量的改动不在局限于当前批处理文件;实质上“endlocal”比较特殊,是可以省略的,也不是一定要与“setlocal”成对出现,当一个或多个“setlocal”没有强制使用“endlocal”时会在批处理文件的末尾自动执行“endlocal”命令来还原初始默认设置。
   当开启延迟环境变量的扩展功能后,对环境变量的修改和引用将会扩展到整个批处理程序中。下面来看看如何使用延迟环境变量的扩展功能?现在使用延迟环境变量扩展功能解决上面遇到的问题,代码如下:

@echo off
setlocal enableDelayedExpansion
set var=before
if "!var!" == "before" (
  set var=after
  if "!var!" == "after" (
    echo 重置var的值成功[var=!var!]
  ) else (
    echo 重置var的值失败[var=!var!]
  )
)
pause>nul

 

在这段代码中,首先使用“setlocal enableDelayedExpansion”语句启用了延迟环境变量扩展功能,保存为批处理文件并执行的结果则为预想的效果“重置var的值成功[var=after]”,代码中并没有强制使用“endlocal”语句停用延迟环境变量扩展功能,但是MS-DOS解释器会在程序的末尾,也就是“pause>nul”语句之后自动调用“endlocal”命令重置MS-DOS环境默认值。
   但是上面的代码与之前的代码还有一处细小的区别,就是这里使用了“!xxx!”的方式来引用变量。然而为什么要使用这种方式呢?“%xxx%”的方式是否可行?答案可想而知“%xxx%”的方式肯定不可行。之前已经介绍过“%xxx%”方式的变量替换原则,当在一条命令的整体语句中时,如果首次遇到“%xxx%”的字符串,则会自动查找并替换该整条语句中的所有“%xxx%”字符串为指定变量的值;正是这个原因,所以提出了延迟环境变量扩展的概念,延迟环境变量扩展就是为了解决整条语句中所有变量被替换的问题,然而在提出延迟环境变量扩展概念的同时扩展了“!xxx!”的变量引用方式,主要用于区别默认的“%xxx%”变量引用方式,而且“!xxx!”变量引用方式只能在延迟环境变量扩展功能开启的环境中才能被解析。
   来总结以下,关于延迟环境变量扩展的用法,延迟环境变量扩展功能主要用于解决像“if”、“for”以及各种复合语句(使用逻辑运算符拼接的语句)等中,用于在语句内部引用修改后的变量,因为默认情况下语句中的变量是被提前替换的,使用延迟环境变量则可以延迟替换过程到解析到该变量时;使用“setlocal enableDelayedExpansion”语句开启延迟环境变量扩展功能后,只能使用“!xxx!”的方式引用变量,表示该变量将被作为延迟环境变量进行处理,如果使用“%xxx%”方式引用将继续作为普通变量处理;开启延迟环境变量扩展功能后可以在必要的时候强制使用“endlocal”或“setlocal disableExtensions”语句停用该功能,默认在程序结尾自动调用“endlocal”语句进行重置。
————————————————
版权声明:本文为CSDN博主「sanqima」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sanqima/article/details/37818115

posted @ 2019-10-18 09:25  QIYUEXIN  阅读(7138)  评论(0编辑  收藏  举报