4.2 環(huán)境變量延遲擴(kuò)展(下)

2022-04-13 15:07 更新

《批處理入門手冊》
四. 環(huán)境變量延遲擴(kuò)展(下)
-----------------------------------------------------------------------------------------------------
4.2 學(xué)習(xí)環(huán)境變量延遲擴(kuò)展

學(xué)習(xí)要點(diǎn):
三,批處理延遲變量(通俗解釋)
四,什么時候使用延遲變量?如何使用?
-----------------------------------------------------------------------------------------------------


三,批處理延遲變量(通俗解釋)
原文地址:http://bbs.bathome.cn/viewthread.php?tid=354

  變量延遲  setlocal EnableDelayedExpansion
  一個讓大多數(shù)新手頭痛的問題,網(wǎng)上教程雖多,但多半都是看不懂的,里面的專業(yè)術(shù)語太多。
以 cn-dos 聯(lián)盟的willsort的這篇教程為例,(個人認(rèn)為是解釋的極具權(quán)威和專業(yè)的)
http://www.cn-dos.net/forum/viewthread.php?tid=20733

  但可能就是因?yàn)閷I(yè),所以才看不懂,因?yàn)閷W(xué)cmd批處理的并不一定都是學(xué)計算機(jī)專業(yè)的。這個鬼東西確實(shí)不太好
理解,在下也是摸爬滾打多時,總結(jié)出一點(diǎn)點(diǎn)經(jīng)驗(yàn),現(xiàn)用通俗的方法解釋出來,希望能給新手些幫助,老鳥們見笑
了,若有不對的地方,歡迎指出。

  言歸正傳
在什么時候需要延遲變量,和該如何引用延遲變量,我想這才是大多數(shù)新手迫切想要知道的問題。
耐心看完下面的內(nèi)容,我想對你應(yīng)該是有幫助的。

  要想了解延遲變量,首先你要明白什么是“復(fù)合語句”好像又來了個“專業(yè)”名詞,別急,這個超好理解。所謂
“復(fù)合語句”就是指一對()里的所有命令。比如for的do后面
如:


for /f "delims=" %%i in (a.txt) do (
      set var=%%i
      echo %%i
      set num=%%i
)

這里do后面的三句命令,在一對()里面,這就叫“復(fù)合語句”,當(dāng)然不止for 還有if 等等。。。
如:


if "%var%"=="abc" (
   echo ok
   set lis=123
)

反正就是凡是()里的所有命令,就叫“復(fù)合語句”
另外:這也是復(fù)合語句 set abc=123&echo %abc% 沒錯,通過管道命令&連接起來的命令,也是復(fù)合語句。

  好,了解了復(fù)合語句,現(xiàn)在開始講延遲變量,也就說,在復(fù)合語句中才要使用延遲變量。
我們先不去理解什么叫“變量的擴(kuò)展”這玩意叫法太專業(yè),我到現(xiàn)在都不太明白,

  我們只要知道在什么時候需要使用延遲變量,如何才能正確提取到我們需要的變量就可以了,這才是我們的目的。
cmd在處理“復(fù)合語句”的時候,如果“復(fù)合語句”中用到了變量,會把變量的值當(dāng)作復(fù)合語句之前變量的值來引用
。如果在此之前變量沒有被賦值,就把它當(dāng)成空值。

例1,


@echo off
for /l %%i in (1 1 10) do (
    set var=%%i
    echo %var%
)
Pause

運(yùn)行上面的代碼,顯示什么?顯示10個echo處于關(guān)閉狀態(tài)。按照邏輯,var的值應(yīng)該依次是 1、2、3........10 才
對??!

這就是因?yàn)闆]有開啟 延遲變量 的緣故,cmd把var的值當(dāng)作復(fù)合語句之前的值來引用,
而在本例中,復(fù)合語句之前并沒有給var定義,所以var的值是空的,所以會顯示10個echo處于關(guān)閉狀態(tài)。

例2,


@echo off
set var=abc
for /l %%i in (1 1 10) do (
    set var=%%i
    echo %var%
)
Pause

運(yùn)行上面的代碼,會顯示什么,大家應(yīng)該知道了吧?

例3,


@echo off
set var=abc
for /l %%i in (1 1 5) do (
    set var%%i=%%i
    echo %var%
)
echo %var1% %var2% %var3% %var4% %var5%
pause

運(yùn)行上面的代碼后,復(fù)合語句中所賦的值全部顯示出來了,這說明什么呢?

說明,在復(fù)合語句中,并不是沒有給變量賦值,只是你若沒有開啟延遲變量,你就沒法在復(fù)合語句中提取到它,要
等復(fù)合語句運(yùn)行完畢后,才能提取到。

變量的表示方法:兩種:  1、%var%   2、!var!
第一種表示方法,大家都知道,第二種就是引用 延遲的變量。
在開啟了延遲變量的情況下,如果在復(fù)合語句之外,用哪種方法表示都可以。但是你若要在復(fù)合語句中引用復(fù)合語
句即時得到的變量,就要用第二種方法??蠢?/p>

例4,


@echo off
setlocal EnableDelayedExpansion
set var=abc
for /l %%i in (1 1 10) do (
    set var=%%i
    echo %var%
    echo !var!
)
Pause

注意:例子中有兩個echo 一個是顯示 %var% 一個是顯示 !var!
結(jié)果很明白了,%var% 顯示的結(jié)果是復(fù)合語句之前變量var的值,而 !var! 顯示的就是復(fù)合語句中即時得到的值。

例5,


@echo off
setlocal EnableDelayedExpansion
for /l %%i in (1 1 5) do (
    set var%%i=%%i
)
echo %var1% %var2% %var3% %var4% %var5%
echo !var1! !var2! !var3! !var4! !var5!
pause

這個例子說明什么,不用再解釋了吧?
說明在開啟了延遲變量的情況下,且在復(fù)合語句之外,用兩種方法都可以表示變量。就說到這吧。以上的解釋,完
全是出于個人的理解,也是為方便非專業(yè)人士理解,解釋肯定有錯誤的地方、就象學(xué)習(xí)英語時,為方便記憶,用漢
字的讀音來作解釋一樣。呵呵,是一種“偏門”各位新手千萬不要把以上所說的當(dāng)成是“真理”,否則就變成是“
誤人”了。
-----------------------------------------------------------------------------------------------------

 


四,什么時候使用延遲變量?如何使用?

  什么時候使用延遲變量?如何使用?這些一直是使新手困惑的地方,那到底是怎么樣的呢?那請看下面的例子,
我們將一步步引導(dǎo)大家。

例1,


@echo off
set /a num=0
for /l %%i in (1 1 3) do (
     Rem ================================
     set /a num =1 
     Rem 原意是變量num的值每次都加1
     Rem ================================
     echo %num%
)
pause>nul

  先猜猜看,運(yùn)行之后的結(jié)果是什么呢?你是不是認(rèn)為它會顯示:1 2 3 呢?我想大部分人會這么認(rèn)為。你再將以
上代碼保存為批處理文件,運(yùn)行,看看結(jié)果。
你會看到,顯示的結(jié)果并不是意料中的 1 2 3 而是 0 0 0,這個是為什么呢?

  原來這個是因?yàn)?,批處理在處理for 或者if 語句中的變量時,先要進(jìn)行預(yù)處理,把其中的用%%括起來的變量,先
替換為語句之前的變量(如上面的代碼,for語句中的%num%早就被替換為語句前的 值:0),所以,for語句運(yùn)行時
,雖然已經(jīng)給變量加了1,但是,值卻不變(因?yàn)閑cho %num%中的%num%早已被替換為:0了)。
那么,要實(shí)現(xiàn)(for或者if)語句中的變量實(shí)時的變化(如這里,我就要將1 2 3 顯示出來)要怎么辦呢?那就要起
用延遲變量,先在批處理中申明:setlocal enabledelayedexpansion 然后,將語句:echo %num%改成!num!(也就
是將“%”改成“!”),這樣就可以達(dá)到效果了,演示代碼:

例2,


@echo off 
Rem ''''///////下面先申明起用延遲變量/////////////
setlocal enabledelayedexpansion
set /a num=0
for /l %%i in (1 1 3) do (
     Rem ================================
     set /a num =1 
     Rem 變量num的值每次都加1
     Rem ================================
     Rem '''''''//////////////////下面的變量不能再用"%"括起來,而應(yīng)該用"!"http:////////////
     echo !num!
)
pause>nul


歸納總結(jié):
1、為什么要用延遲變量?
讓if語句和for語句中的變量實(shí)時變化;

2、什么時候用延遲變量?
一般是用在 for 語句和 if 語句中;

3、怎么用延遲變量?
先在批處理中申明起用延遲變量:setlocal enabledelayedexpansion
然后將 for 語句、if語句中的變量用兩個"!"括起來即可

4、其實(shí)在使用變量嵌套變量也可以使用變量延遲的。

例3,


@echo off
set a=1
set b1=10
echo %b%a%%
pause

執(zhí)行顯示,得到 %b1%

其實(shí)我想得到的是 賦予b1的值,即 10  那么如何實(shí)現(xiàn)呢?將上例修改如下,

例4,


@echo off
set a=1&set b1=10
call,echo %%b%a%%%
pause>nul

call 這里實(shí)際是對命令行進(jìn)行重新組織擴(kuò)展,先擴(kuò)展%%b%a%%%里面的%a%,使%a%變成a的值1,再用cal來擴(kuò)展%b1%
。

也可以用變量延遲來實(shí)現(xiàn),方法如下:

例5,


@echo off
set /a a=1,b1=10
Setlocal EnableDelayedExpansion
echo:!b%a%! ...
pause


call 在這里的用法實(shí)際是變量延遲的一種快捷方式,變量延遲一般用在for的循環(huán)體里面。
call,%%b%a%%% 這里的逗號實(shí)際是一個分隔符,和空格一樣,還有很多分隔符可用,比如上例中的 echo:!b%a%! ,
當(dāng)然并不是所有的命令都可以這樣用,看情況而定……


例6,


@echo off&setlocal enabledelayedexpansion
set a=1000
set b=dd
set a%b%=9000
set c=!a%b%! 
echo %c%
pause

執(zhí)行一下,看看顯示的將是什么?為什么是這樣?相信通過例4,例5你也能分析得出來吧?
-----------------------------------------------------------------------------------------------------

 


注:以上文章在編輯整理時稍有修改!
Januapr編輯于2009-09-15 星期二14:48:57.46


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號