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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM