1. 程式人生 > >dos下 和 批處理中的 for 語句的基本用法

dos下 和 批處理中的 for 語句的基本用法

for 語句的基本用法 :

    最複雜的for 語句,也有其基本形態,它的模樣是這樣的: 

   在cmd 視窗中:for %I in (command1) do command2 

   在批處理檔案中:for %%I in (command1) do command2 

   之所以要區分 cmd 視窗和批處理檔案兩種環境,是因為在這兩種環境下,命令語句表現出來的行為雖然基本一樣,但是在細節上還是稍有不同,最明顯的一個差異就是:在cmd 視窗中,for 之後的形式變數I 必須使用單百分號引用,即%I;而在批處理檔案中,引用形式變數I 必須使用雙百分號,即%%I。為了方便起見,若不是特別強調,以下的講解都以批處理檔案環境為例。 

   我們先來看一下for 語句的基本要素都有些什麼: 

   1、for、in 和do 是  for 語句的關鍵字,它們三個缺一不可; 

   2、%%I 是for 語句中對形式變數的引用,就算它在do 後的語句中沒有參與語句的執行,也是必須出現的; 

   3、in 之後,do 之前的括號不能省略; 

   4、command1 表示字串或變數,command2 表示字串、變數或命令語句; 

   5、for /d  注意:for 後 可以 加 /f /r /l /d 這四個 引數,現在 先 介紹 /d 引數的 作用,一句話 /d 用於 搜尋 目錄 或 資料夾,但 不會搜尋檔案,也不搜尋 子目錄

   現在,你可能已經會寫一個簡單的for 語句了,比如: 

在 一個 cmd.bat 檔案裡 寫,寫 如下 兩條 命令:

for /d %%i in (*) do echo %%i
pause

[code1] 

@echo off 

for %%I in (bbs.bathome.cn) do echo %%I 

pause 

   儲存為批處理檔案並執行,將會在彈出的批處理視窗中看到這樣的資訊: 

[result1] 

bbs.bathome.cn 

請按任意鍵繼續... 

  先來分析一下 for 語句的一些注意事項,之後,再讓大家看看更為強大的for 語句例項。 

   1、for 語句的形式變數 I,可以換成 26 個字母中的任意一個,這些字母會區分大小寫

,也就是說,%%I 和%%i 會被認為不是同一個變數;形式變數 I還可以換成其他的字元,但是,為了不與批處理中的%0~%9 這10 個形式變數發生衝突,請不要隨意把%%I 替換為%%0  ~%%9 中的任意一個;

   2、in 和do 之間的command1 表示的字串或變數可以是一個,也可以是多個,每一個字串或變數,我們稱之為一個元素,每個元素之間,用空格鍵、跳格鍵、逗號、分號或等號分隔;

   3、for 語句依次提取 command1 中的每一個元素,把它的值賦予形式變數I,帶到do 後的command2 中參與命令的執行;並且每次只提取一個元素,然後執行一次 do 後的命令語句,而無論這個元素是否被帶到 command2 中參與了command2 的執行;當執行完一次do 後的語句之後,再提取command1 中的下一個元素,再執行一次 command2,如此迴圈,直到 command1 中的所有元素都已經被提取完畢,該for 語句才宣告執行結束; 

   其中,第3 點是最為關鍵的,它描述了for 語句的執行過程,是for 語句的精髓所在,大家一定要牢記這一條,才能深刻理解更為複雜的for 流程。 

   有了以上的基礎,我們再來看一個例子,這個例子修改了code1 的部分內容,

結果將大不一樣: 

[code2] 

@echo off 

for %%I in (bbs,bathome,cn) do echo %%I 

pause 

   和code1 的執行結果相比,code2 的執行結果發生瞭如下變化: 

   1、顯示結果分成了3 行(不算最後一行中文提示); 

   2、每一行都從逗號處被切分; 

   如果把  bbs.bathome.cn  這個字串中的點號換為 空格、跳格 或 等號,執行結果將和code2 的執行結果別無二致。 

以下這段程式碼的 功能是 :檢測當前硬碟都有哪些分割槽

[code3] 

@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 

 第二句 可以 用 for %%i in (*) do echo "%%i"  代替;

   想列出當前目錄下所有的文字檔案嗎?請用下面的程式碼: 

@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 /f  用法詳解 

    前言 

   for /f  是個十分強大的傢伙。 

   如果說,for 語句是批處理中最強大的語句的話,那麼,for /f  就是精華中的精華。 

   for  /f  的強大,和它擁有眾多的開關密切相關。因為開關眾多,所以用法複雜,本章將分成若干小節,為大家逐一介紹強大的  for /f  語句。 

    (一)  為解析文字而生:f or /f  的基本用法 

   所有的物件,無論是檔案、窗體、還是控制元件,在所有的非機器語言看來,無外乎都是形如"c:\test.txt"、"CWnd"之類的文字資訊;而所有的物件,具體的如ini

檔案中的某條配置資訊、登錄檔中的某個鍵值、資料庫中的某條記錄„„都只有轉化為具有一定格式的文字資訊,方可被程式碼識別、操控。可以說,程式設計的很大

一部分工作,都是在絞盡腦汁想方設法如何提取這些文字資訊。 

   而提取文字資訊,則是for /f 的拿手好戲:讀取檔案內容;提取某幾行字元;擷取某個字元片段;對提取到的內容再切分、打亂、雜糅„„只要你所能想到的花樣,for /f  都會想方設法幫你辦到,因為,for /f  就是被設計成專門用於解析文字的。 

   先來看個例子。 

   假如有個文字檔案test.txt,內容如下: 

[txt1] 

論壇的目標是:不求最大,但求最好,做最實用的批處理論壇。 

論壇地址:bbs.bathome.cn。 

這裡是:新手晉級的福地,高手論劍的天堂。 

   那麼,將如下程式碼儲存為test.cmd,並放在test.txt 同一目錄下執行,將會在螢幕上原樣顯示test.txt 的內容: 

[code4] 

@echo off 

for /f %%i in (test.txt) do echo %%i 

pause 

   這段程式碼,主要是讓你樹立這樣一種觀念:讀取文字檔案的內容,請使用  for /f  語句! 

   進階話題:for /f  語句是把整個test.txt 一次性顯示出來的? 

   在這段程式碼中,雖然執行結果是把 test.txt 中的所有內容都顯示出來了,貌似  for /f  語句是把整個test.txt 一次性顯示到螢幕上,實際上並非如此。 

   無論for 語句做何種變化,它的執行過程仍然遵循基本的for 流程:依次處理每個元素,直到所有的元素都被處理為止。只不過在for /f 語句中,這裡的元素是指檔案中的每一行,也就是說,for /f  語句是以行為單位處理文字檔案的。這是一條極為重要的規則,在上一章中也強調過它的重要性,希望在接下來的學習過程中,你能時刻牢記這一原則,那麼,很多問題將會迎刃而解。以下是驗證這一說法的演示程式碼(在[code4]的基礎上添加了&pause 語句): 

[code5] 

@echo off 

for /f %%i in (test.txt) do echo %%i&pause 

pause 

    (二)  切分字串的利器:delims= 

   也許你對[code4]這段程式碼不屑一顧:不就是把test.txt 的內容顯示出來了麼?

好像用處不大啊。 

   好吧,我們來玩個魔術。 

   還是[txt1]這段文字,把[code4]改造一下: 

[code6] 

@echo off 

for /f "delims=," %%i in (test.txt) do echo %%i 

pause 

   再次執行test.cmd,看到什麼變化了嗎?! 

[result2] 

論壇的目標是:不求最大 

論壇地址:bbs.bathome.cn。 

這裡是:新手晉級的福地 

請按任意鍵繼續... 

   結果,你驚奇地發現,每行第一個逗號之後的所有內容都不見了(如果有不存在逗號的行,則保留原樣),也就說,你成功地提取到了每行第一個逗號之前的所有內容! 

   試想一下,這段程式碼會有什麼用呢? 

   如果別人給了你一個軟體清單,每行都是"英文軟體名(逗號)中文軟體名"的格式,而你卻只想保留英文名的時候,這段程式碼將是多麼有用啊!再假設,有這麼一個IP 檔案,第一列是數字格式的IP 地址,第二列是具體的空間地址,列與列之間用逗號分隔,而你想提取其中數字格式的 IP,呵呵,我不說你也知道該怎麼辦了吧? 

   要是文字內容不是以逗號分隔,而是以其他符號分隔,那麼,把"delims=,"的逗號換成相應的符號就可以了。 

   在這裡,我們引入了一個新的開關:"delims=,",它的含義是:以逗號作為被處理的字串的分隔符號。 

   在批處理中,指定分隔符號的方法是:新增一個形如  "delims=符號列表"  的開關,這樣,被處理的每行字串都會被符號列表中羅列出來的符號切分開來。 

   需要注意的是:如果沒有指定"delims=符號列表"這個開關,那麼,for /f  語句預設以空格鍵或跳格鍵作為分隔符號。請把[txt1]中不同位置上的標點符號改為空格或跳格,再執行[code4]試試。 

=============================================

   進階話題:如果我要指定的符號不止一個,該怎麼辦? 

   在上面的講解中,我提到了指定分隔符號的方法:新增一個形如"delims=符

號列表"的開關。不知道你注意到沒有,我的說法是"符號列表"而非"符號",這是

大有講究的,因為,你可以一次性指定多個分隔符號! 

10 

   還是以[txt1]為例,把[code6]再改造一下: 

[code7] 

@echo off 

for /f "delims=.," %%i in (test.txt) do echo %%i 

pause 

   結果顯示: 

[result3] 

論壇的目標是:不求最大 

論壇地址:bbs 

這裡是:新手晉級的福地 

請按任意鍵繼續... 

   這樣,第一個點號或第一個逗號之前的內容都被提取出來了。 

   [code7]的執行過程是:逐行讀取 test.txt 中的內容,以點號和逗號切分每一

行的內容(不存在點號和逗號的行,則不再切分,為了描述的方便,我們把被點

號或逗號切分的一個一個的字串片段,稱之為節),然後,for /f  會提取第一節

的內容作為最終結果,顯示在螢幕上。需要注意的是,在這裡,所有行的字串

被切分成了兩個以上的節,但是,[code7]的程式碼只會提取第一節字串的內容,

因為  for /f  語句預設只提取第一節的符串。 

    (三)  定點提取:tokens= 

   上一節在講解  delims=  的時候,我一再強調  for  /f  預設只能提取到第一節

的內容,現在我們來思考一個問題:如果我要提取的內容不在第一節上,那怎麼

辦? 

   這回,就該輪到  tokens=  出馬了。 

   tokens=  後面一般跟的是數字,如  tokens=2,也可以跟多個,但是每個數字

之間用逗號分隔,如  tokens=3,5,8,它們的含義分別是:提取第2 節字串、提

取第3、第5 和第8 節字串。注意,這裡所說的“節”,是由  delims=  這一開

關劃分的,它的內容並不是一成不變的。 

   下面來看一個例子: 

11 

[txt2] 

尺有所短,寸有所長,學好批處理沒商量,考慮問題複雜化,解決問題簡潔化。 

   對[txt2]這段文字,假設它們儲存在檔案 test.txt 中,如果我想提取“學好批

處理沒商量”這句話,該如何寫程式碼呢? 

   我們稍微觀察一下[txt2]就會發現,如果以逗號作為切分符號,就正好可以

把“學好批處理沒商量”化為單獨的一“節”,結合上一節的講解,我們知道,

"delims=,"  這個開關是不可缺少的,而要提取的內容在以逗號切分的第3 節上,

那麼,tokens=  後面的數字就應該是3 了,最終的程式碼如下: 

[code8] 

@echo off 

for /f "delims=,  tokens=3" %%i in (test.txt) do echo %%i 

pause 

   如果我們現在要提取的不只一個“節”,而是多個,那又怎麼辦呢?比如,

要提取以逗號切分的第2 節和第5 節字串,是寫成這樣嗎? 

[code9] 

@echo off 

for /f "delims=,  tokens=2,5" %%i in (test.txt) do echo %%i 

pause 

   執行批處理後發現,執行結果只顯示了第2 節的內容。 

   原來,echo  後面的  %%i  只接收到了  tokens=2,5  中第一個數值2 所代表的

那個字串,而第二個數值5 所代表的字串因為沒有變數來接收,所以就無法

在執行結果中顯示出來了。 

   那麼,要如何接收  tokens=  後面多個數值所指代的內容呢? 

   for /f  語句對這種情況做如下規定: 

   如果  tokens=  後面指定了多個數字,如果形式變數為%%i,那麼,第一個

數字指代的內容用第一個形式變數%%i 來接收,第二個數字指代的內容用第二

個形式變數%%j 來接收,第三個數字指代的內容用第三個形式變數%%k 來接

收„„第N 個數字指代的內容用第N 個形式變數來接收,其中,形式變數遵循

字母的排序,第 N 個形式變數具體是什麼符號,由第一個形式變數來決定:如

果第一個形式變數是%%i,那麼,第二個形式變數就是%%j;如果第一個形式

變數用的是%%x,那麼,第二個形式變數就是%%y。 

   現在回頭去看[code9],你應該知道如何修改才能滿足題目的要求了吧?修改

12 

結果如下: 

[code10] 

@echo off 

for /f "delims=,  tokens=2,5" %%i in (test.txt) do echo %%i %%j 

pause 

   如果有這樣一個要求:顯示[txt2]中的內容,但是逗號要替換成空格,如何

編寫程式碼? 

   結合上面所學的內容,稍加思索,你可能很快就得出了答案: 

[code11] 

@echo off 

for  /f  "delims= ,   tokens=1,2,3,4,5"  %%i  in  (test.txt)  do 

echo %%i %%j %%k %%l %%m 

pause 

   寫完之後,你可能意識到這樣一個問題:假如要提取的“節”數不是5,而

是10,或者20,或者更多,難道我也得從1 寫到10、20 或者更多嗎?有沒有更

簡潔的寫法呢? 

   答案是有的,那就是:如果要提取的內容是連續的多“節”的話,那麼,連

續的數字可以只寫最小值和最大值,中間用短橫連線起來即可,比如 

tokens=1,2,3,4,5  可以簡寫為  tokens=1-5  。 

   還可以把這個表示式寫得更復雜一點:tokens=1,2-5 ,tokens=1-3,4,5 ,

tokens=1-4,5„„怎麼方便就怎麼寫吧。 

   大家可能還看到一種比較怪異的寫法: 

[code12] 

@echo off 

for /f "delims=,  tokens=1,*" %%i in (test.txt) do echo %%i %%j 

pause 

   結果,第一個逗號不見了,取代它的是一個空格符號,其餘部分保持不變。 

   其中奧妙就在這個星號上面。 

    tokens=後面所接的星號具備這樣的功能:字串從左往右被切分成緊跟在*

之前的數值所表示的節數之後,字串的其餘部分保持不變,整體被*所表示的

一個變數接收。 

13 

   理論講解是比較枯燥的,特別是為了嚴密起見,還使用了很多限定性的修飾

詞,導致句子很長,增加了理解的難度,我們還是結合[code12]來講解一下吧。 

   [txt2]  的內容被切分,切分符號為逗號,當切分完第一節之後,切分動作不

再繼續下去,因為  tokens=1,*  中,星號前面緊跟的是數字 1;第一節字串被

切分完之後,其餘部分字串不做任何切分,整體作為第二節字串,這樣,[txt2]

就被切分成了兩節,分別被變數%%i 和變數%%j 接收。 

   以上幾種切分方式可以結合在一起使用。不知道下面這段程式碼的含義你是否

看得懂,如果看不懂的話,那就執行一下程式碼,然後反覆揣摩,你一定會更加深

刻地理解本節所講解的內容的: 

[code13] 

@echo off 

for /f "delims=,  tokens=1,3-4,*" %%i in (test.txt) do echo %%i %%j %%k %%l 

pause 

    (四)  跳過無關內容,直奔主題:skip=n 

   很多時候,有用的資訊並不是貫穿文字內容的始終,而是位於第 N 行之後

的行內,為了提高文字處理的效率,或者不受多餘資訊的干擾,for  /f  允許你跳

過這些無用的行,直接從第N+1 行開始處理,這個時候,就需要使用引數  skip=n,

其中,n 是一個正整數,表示要跳過的行數。例如: 

[code14] 

@echo off 

for /f "skip=2" %%i in (test.txt) do echo %%i 

pause 

   這段程式碼將跳過頭兩行內容,從第3 行起顯示test.txt 中的資訊。 

    (五)  忽略以指定字元打頭的行:eol= 

   在cmd 視窗中敲入:for /?,相關的解釋為: 

[quote] 

eol=c                      -  指一個行註釋字元的結尾(就一個) 

[/quote] 

14 

[quote] 

FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do @echo %i %j %k 

     會分析  myfile.txt  中的每一行,忽略以分號打頭的那些行„„ 

[/quote] 

   第一條解釋狗屁不通,頗為費解:行註釋字元的結尾是什麼意思?“(就一

個)”怎麼回事?結合第二條解釋,才知道eol 有忽略指定行的功能。但是,這兩

條解釋是互相矛盾的:到底是忽略以指定字元打頭的行,還是忽略以指定字元結

尾的行? 

   實踐是檢驗真理的唯一標準,還是用程式碼來檢驗一下eol 的作用吧: 

[code15] 

@echo off 

for /f "eol=;" %%i in (test.txt) do echo %%i 

pause 

   結果,那些以分號打頭的行沒有顯示出來。 

   由此可見,第二條解釋是正確的,eol=  的準確含義是:忽略以指定字元打

頭的行。而第一條的“結尾”純屬微軟在信口開河。 

   那麼,“(就一個)”又作何解釋呢? 

   試試這個程式碼: 

[code16] 

@echo off 

for /f "eol=,;" %%i in (test.txt) do echo %%i 

pause 

   此時,螢幕上出現  此時不應有  ;"。  的報錯資訊。可見,在指定字元的時

候,只能指定1 個——在很多時候,我對這樣的設計頗有微詞而又無可奈何:為

什麼只能指定1 個而不是多個?要忽略多個還得又是 if 又是 findstr 加管道來多

次過濾,那效率實在太低下了——能用到的功能基本上都提供,但是卻又做不到

更好,批處理,你的功能為什麼那麼弱? 

   不知道大家注意到沒有,如果 test.txt 中有以分號打頭的行,那麼,這些行

在程式碼[code14]的執行結果中將憑空消失。 

   原來,for /f  語句是預設忽略以分號打頭的行內容的,正如它預設以空格鍵

或跳格鍵作為字串的切分字元一樣。 

   很多時候,我們可以充分利用這個特點,比如,在設計即將用for 讀取的配

置檔案的時候,可以在註釋文字的行首加上分號,例如在編寫病毒檔案查殺程式碼

15 

的時候,可以通過 for 語句來讀取病毒檔案列表,那麼,病毒檔案列表.ini 這個

配置檔案可以這樣寫: 

;以下是常見的病毒檔案,請見一個殺一個^_^ 

;copyleft:沒有 

qq.exe 

msn.exe 

iexplore.exe 

   如果要取消這個預設設定,可選擇的辦法是: 

   1、為eol=指定另外一個字元; 

   2、使用  for /f "eol="  語句,也就是說,強制指定字元為空,就像對付delims=

一樣。 

    (六)如何決定該使用  f or  /f  的哪種句式?(兼談

usebackq 的使用) 

   for /f %%i in („„) do („„)  語句有好幾種變形語句,不同之處在於第一個

括號裡的內容:有的是用單引號括起來,有的是用雙引號包住,有的不用任何符

號包裹,具體格式為: 

   1、for /f %%i in (檔名) do („„) 

   2、for /f %%i in ('命令語句') do („„) 

   3、for /f %%i in ("字串") do („„) 

   看到這裡,我想很多人可能已經開始犯了迷糊了:如果要解決一個具體問題,

面對這麼多的選擇,如何決定該使用哪一條呢? 

   實際上,當我在上面羅列這些語句的時候,已經有所提示了,不知道你是否

注意到了。 

   如果你一時無法參透其中奧妙,那也無妨,請聽我一一道來便是。 

   1、當你希望讀取文字檔案中的內容的話,第一個括號中不用任何符號包裹,

應該使用的是第1 條語句;例如:你想顯示test.txt 中的內容,那麼,就使用  for 

/f %%i in (test.txt) do echo %%i; 

   2、當你讀取的是命令語句執行結果中的內容的話,第一個括號中的命令語

句必須使用單引號包裹,應該使用的是第2 條語句;例如:你想顯示當前目錄下

16 

檔名中含有test 字串的文字檔案的時候,應該使用  for /f %%i in ('dir /a-d 

/b *test*.txt') do echo %%i  這樣的語句; 

   3、當你要處理的是一個字串的時候,第一個括號中的內容必須用雙引號

括起來,應該是用的是第 3 條語句;例如:當你想把 bbs.bathome.cn 這串字元

中的點號換為短橫線並顯示出來的話,可以使用  for  /f  "delims=. 

tokens=1-3"  %%i  in  ("bbs.bathome.cn")  do  echo  %%i-%%j-%%k  這樣的語

句。 

   很顯然,第一個括號裡是否需要用符號包裹起來,以及使用什麼樣的符號包

裹,取決於要處理的物件屬於什麼型別:如果是檔案,則無需包裹;如果是命令

語句,則用單引號包裹;如果是字串,則使用雙引號括起來。 

   當然,事情並不是絕對如此,如果細心的你想到了批處理中難纏的特殊字元,

你肯定會頭大如鬥。 

   或許你頭腦中靈光一閃,已經想到了一個十分頭痛的問題:在第1 條語句中,

如果檔名中含有空格或&,該怎麼辦? 

   照舊嗎? 

   拿個叫  test 1.txt  的檔案來試試。 

   你很快寫好了程式碼,新建檔案-->碼字-->儲存為批處理,前後費時不到 1 分

鍾: 

[code17] 

@echo off 

for /f %%i in (test 1.txt) do echo %%i 

pause 

   你興沖沖地雙擊批處理,執行後,螢幕上出現了可恥的報錯資訊:系統找不

到檔案  test  。 

   當你把  test 1.txt  換成  test&1.txt  後,更怪異的事情發生了:CMD 視窗在你

眼前一閃而過,然後,優雅地消失了。 

   你可能覺得自己的程式碼寫錯了某些符號,你再仔細的檢查了一次,確認沒有

筆誤,然後,你再次雙擊批處理,結果問題照舊;你開始懷疑其他程式對它可能

有影響,於是關掉其他視窗,再運行了一次,問題依舊;你不服氣地連續運行了

好幾次,還是同樣的結果。 

   怪哉! 

   你一拍大腿,猛然想起了一件事:當路徑中含有特殊字元的時候,應該使用

引號把路徑括起來。對,就是它了! 

17 

   但是,當你把程式碼寫出來之後,你很快就焉了:for /f %%i in ("test 1.txt") do 

echo  %%i,這不就是上面提到的第3 條  for  /f  命令的格式嗎?批處理會把  test 

1.txt  這個檔名識別為字串啊! 

   你百無聊賴地在CMD 視窗中輸入  for /?  ,並重重地敲下了回車,漫無目的

地在幫助資訊中尋找,希望能找到點什麼。 

   結果還真讓你到了點什麼。 

   你看到了這樣的描述: 

         usebackq                -  指定新語法已在下類情況中使用: 

                           在作為命令執行一個後引號的字串並且一個單 

                           引號字元為文字字串命令並允許在  filenameset 

                            中使用雙引號擴起檔名稱。 

   但是,通讀一遍之後,你卻如墜五里霧中,不知所云。 

   還好,下面有個例子,並配有簡單的說明: 

       FOR /F "usebackq delims==" %i IN (`set`) DO @echo %i 

     會列舉當前環境中的環境變數名稱。 

   你仔細對比了 for  /f 語句使用usebackq 和不使用usebackq 時在寫法上的差

別,很快就找到了答案:當使用了 usebackq 之後,如果第一個括號中是一條命

令語句,那麼,就要把單引號'改成後引號`(鍵盤左上角esc 鍵下面的那個按鍵,

與~在同一鍵位上)。 

   回過頭去再看那段關於 usebackq 的描述,字斟句酌,反覆揣摩,終於被你

破譯了天機:usebackq  是一個增強型引數,當使用了這個引數之後,原來的for

語句中第一個括號內的寫法要做如下變動:如果第一個括號裡的物件是一條命

令語句的話,原來的單引號'要改為後引號`;如果第一個括號裡的物件是字串

的話,原來的雙引號"要改為單引號';如果第一個括號裡的物件是檔名的話,

要用雙引號"括起來。 

   驗證一下,把[code17]改寫成如下程式碼: 

[code18] 

@echo off 

for /f "usebackq" %%i in ("test 1.txt") do echo %%i 

pause 

   測試通過! 

18 

   此時,你很可能會仰天長嘆:Shit,微軟這該死的機器翻譯! 

   至於把[code17]程式碼中的空格換成&後,CMD 視窗會直接退出,那是因為&

是複合語句的連線符,CMD 在預處理的時候,會優先把&前後兩部分作為兩條

語句來解析,而不是大家想象中的一條完整的for 語句,從而產生了嚴重的語法

錯誤。因為牽涉到預處理機制問題,不屬於本節要討論的內容,在此不做詳細講

解。 

   這個時候,我們會吃驚地發現,區區一條for 語句,竟然有多達6 種句型: 

   1、for /f %%i in (檔名) do („„) 

   2、for /f %%i in ('命令語句') do („„) 

   3、for /f %%i in ("字串") do („„) 

   4、for /f "usebackq" %%i in ("檔名") do („„) 

   5、for /f "usebackq" %%i in (`命令語句`) do („„) 

   6、for /f "usebackq" %%i in ('字串') do („„) 

   其中,4、5、6 由1、2、3 發展而來,他們有這樣的對應關係:1-->4、2-->5、

3-->6。 

   好在後3 種情形並不常用,所以,牢牢掌握好前三種句型的適用情形就可以

了,否則,要在這麼多句型中確定選擇哪一條語句來使用,還真有點讓人頭腦發

懵。 

   至於  for /f  為什麼要增加usebacq 引數,我只為第4 條語句找到了合理的解

釋:為了相容檔名中所帶的空格或&。它在第 5、6 條語句中為什麼還有存在

的必要,我也不是很明白,這有待於各位去慢慢發現。