Windows bat指令碼之for迴圈之 一
正如色彩繽紛的七彩光芒是由紅綠藍三原色構成的一樣,最複雜的for語句,也有其基本形態,它的模樣是這樣的:
在cmd視窗中:for %I in (command1) do command2
在批處理檔案中:for %%I in (command1) do command2
之所以要區分cmd視窗和批處理檔案兩種環境,是因為在這兩種環境下,命令語句表現出來的行為雖然基本一樣,但是在細節上還是稍有不同,最明顯的一個差異就是:在cmd視窗中,for之後的形式變數I必須使用單百分號引用,即%I;而在批處理檔案中,引用形式變數I必須使用雙百分號,即%%I。為了方便起見,若不是特別強調,以下的講解都以批處理檔案環境為例。
我們先來看一下for語句的基本要素都有些什麼:
- for、in和do是for語句的關鍵字,它們三個缺一不可;
- %%I是for語句中對形式變數的引用,就算它在do後的語句中沒有參與語句的執行,也是必須出現的;
- in之後,do之前的括號不能省略;
- 、command1表示字串或變數,command2表示字串、變數或命令語句;
現在,你可能已經會寫一個簡單的for語句了,比如:
@echo off
for %%I in (bbs.bathome.cn) do echo %%I
pause
儲存為批處理檔案並執行,將會在彈出的批處理視窗中看到這樣的資訊:
很快地,你會覺得這個for語句是如此的簡單,簡單到你絲毫感受不出它的強大:這個for語句,和我直接用echo語句沒什麼兩樣啊!
是的,演示程式碼永遠都只是演示而已,就像大多數高階語言的教科書一樣,在引導新手學習的時候,基本上都是千篇一律地告訴大家如何編寫一個能顯示 hello world! 的視窗,從這些演示程式碼中,你看不到它們具有多少實用性,你只是感到有點好奇:咦,居然彈出了一個視窗?片刻之後,你就會覺得索然無味。
那好吧,為了讓大家對for更加感興趣,我們先來分析一下for語句的一些注意事項,之後,再讓大家看看更為強大的for語句例項。
- for語句的形式變數I,可以換成26個字母中的任意一個,這些字母會區分大小寫,也就是說,%%I和%%i會被認為不是同一個變數;形式變數I還可以換成其他的字元,但是,為了不與批處理中的%0~%9這10個形式變數發生衝突,請不要隨意把%%I替換為%%0~%%9中的任意一個;
- in和do之間的command1表示的字串或變數可以是一個,也可以是多個,每一個字串或變數,我們稱之為一個元素,每個元素之間,用空格鍵、跳格鍵、逗號、分號或等號分隔;
for語句依次提取command1中的每一個元素,把它的值賦予形式變數I,帶到do後的command2中參與命令的執行;並且每次只提取一個元素,然後執行一次do後的命令語句,而無論這個元素是否被帶到command2中參與了command2的執行;當執行完一次do後的語句之後,再提取command1中的下一個元素,再執行一次command2,如此迴圈,直到command1中的所有元素都已經被提取完畢,該for語句才宣告執行結束;
其中,第3點是最為關鍵的,它描述了for語句的執行過程,是for語句的精髓所在,大家一定要牢記這一條,才能深刻理解更為複雜的for流程。
有了以上的基礎,我們再來看一個例子,這個例子修改了code1的部分內容,結果將大不一樣:
@echo off
for %%I in (bbs,bathome,cn) do echo %%I
pause
和code1的執行結果相比,code2的執行結果發生瞭如下變化:
- 顯示結果分成了3行(不算最後一行中文提示);
每一行都從逗號處被切分;
如果把 bbs.bathome.cn 這個字串中的點號換為空格、跳格或等號,執行結果將和code2的執行結果別無二致。現在,我們來分析一下code2程式碼中for語句的執行過程:
首先,for語句以逗號為分隔符,把 bbs,bathome,cn 這個字串切分成三個元素:bbs、bathome和cn,由此決定了do後的語句將會被執行3次;
然後,第一次執行過程是這樣的:先把 bbs 這個字串作為形式變數I的值,帶入do後的語句中加以執行,也就是執行 echo %%I 語句,此時的I值為bbs,因此,第一次執行的結果,將會在螢幕上顯示bbs這個字串;第二次執行和第一次執行的過程是一樣的,只不過此時I的值已經被替換為command1中的第二個元素了,也就是 bathome 這個字串;如此迴圈,當第三次echo執行完畢之後,整條for語句才算執行完畢,此時,將執行下一條語句,也就是pause命令。其實,這個例子只比上一個例子多了一點花樣,有趣了那麼一點點:一條for語句的執行結果居然被分成了3行!
為了讓大家見識一下for的真正威力,本人絞盡腦汁,翻帖無數,不得要領,萬般無奈之下,只好亮出了塵封在箱底多年的一段程式碼:檢測當前硬碟都有哪些分割槽^_^
@echo off
set str=c d e f g h i j k l m n o p q r s t u v w x y z
echo 當前硬碟的分割槽有:
for %%i in (%str%) do if exist %%i: echo %%i:
pause
這段程式碼能檢測硬碟都有哪些分割槽,包括U盤和行動硬碟的分割槽,但是,當光碟機中有盤的時候,也會被列出來,這是本程式碼的一個缺憾,在以後的講解中,我將向大家講述如何消除這個瑕疵,敬請關注本系列的後續章節。
高階應用:
想知道當前目錄下都有哪些檔案嗎?請用下面的程式碼:
@echo off
for %%i in (*.*) do echo "%%i"
pause
想列出當前目錄下所有的文字檔案嗎?請用下面的程式碼:
@echo off
for %%i in (*.txt) do echo "%%i"
pause
想列出只用兩個字元作為檔名的文字檔案嗎?請用下面的程式碼:
@echo off
for %%i in (??.txt) do echo "%%i"
pause
題外話:
1、列出當前目錄下各種檔案的方法,最簡單的還是用dir命令,但是,從以上程式碼中,各位可以加深對for語句執行流程的理解(用到了萬用字元*和?);
2、注意:以上程式碼不能列出含有隱藏或系統屬性的檔案;
練習:用for語句建立test1.txt、test2.txt和test3.txt三個文字檔案。