dos下 和 批处理中的 for 语句的基本用法
原文地址:http://blog.csdn.net/wh_19910525/article/details/7912440
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 條語句中為什么還有存在
的必要,我也不是很明白,這有待于各位去慢慢發現。總結
以上是生活随笔為你收集整理的dos下 和 批处理中的 for 语句的基本用法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ubuntu下取消MySQL自动启动
- 下一篇: linux下初次安装mysql使用指南