FOR這條命令基本上都被用來處理文本,但還有其它一些好用的功能!
看看他的基本格式(這里我引用的是批處理中的格式,直接在命令行僅僅須要一個%號)
FOR 參數 %%變量名 IN (相關文件或命令) DO 運行的命令
參數:FOR有4個參數 /d /l /r /f 他們的作用我在以下用樣例解釋
%%變量名 :這個變量名能夠是小寫a-z或者大寫A-Z,他們區分大寫和小寫,FOR會把每一個讀取到的值給他;
IN:命令的格式,照寫就是了;
(相關文件或命令) :FOR要把什么東西讀取然后賦值給變量,看以下的樣例
do:命令的格式,照寫就是了!
運行的命令:對每一個變量的值要運行什么操作就寫在這.
能夠在CMD輸入for /?看系統提供的幫助!對照一下
FOR %%variable IN (set) DO command [command-parameters]
%%variable 指定一個單一字母可替換的參數。
(set) 指定一個或一組文件。能夠使用通配符。
command 指定對每一個文件運行的命令。
command-parameters
為特定命令指定參數或命令行開關。
如今開始講每一個參數的意思
/d
僅為文件夾
假設 Set (也就是我上面寫的 "相關文件或命令") 包括通配符(* 和 ?),將對與 Set 相匹配的每一個目
錄(而不是指定文件夾中的文件組)運行指定的 Command。
系統幫助的格式:FOR /D %%variable IN (set) DO command
他主要用於文件夾搜索,不會搜索文件,看這種樣例
@echo off
for /d %%i in (*) do @echo %%i
pause
把他保存放在C盤根文件夾運行,就會把C盤文件夾下的所有文件夾名字打印出來,而文件名稱字一個也不顯示!
在來一個,比方我們要把當前路徑下文件夾的名字僅僅有1-3個字母的打出來
@echo off
for /d %%i in (???) do @echo %%i
pause
這種話假設你當前文件夾下有文件夾名字僅僅有1-3個字母的,就會顯示出來,沒有就不顯示了
思考題目:
@echo off
for /d %%i in (window?) do @echo %%i
pause
保存到C盤下運行,會顯示什么呢?自己看吧!
/D參數僅僅能顯示當前文件夾下的文件夾名字,這個大家要注意!
/R
遞歸
進入根文件夾樹 [Drive:]Path,在樹的每一個文件夾中運行 for 語句。假設在 /R 后沒有指定文件夾,則覺得是
當前文件夾。假設 Set 僅僅是一個句點 (.),則僅僅枚舉文件夾樹。
系統幫助的格式:FOR /R [[drive:]path] %%variable IN (set) DO command
上面我們知道,/D僅僅能顯示當前路徑下的文件夾名字,那么如今這個/R也是和文件夾有關,他能干嘛呢?放心他比
/D強大多了!
他能夠把當前或者你指定路徑下的文件名稱字所有讀取,注意是文件名稱字,有什么用看樣例!
@echo off
for /r c:/ %%i in (*.exe) do @echo %%i
pause
咋們把這個BAT保存到D盤隨便哪里然后運行,我會就會看到,他把C盤根文件夾,和每一個文件夾的子文件夾以下所有
的EXE文件都列出來了,這里的c:/就是文件夾了。
再來一個
@echo off
for /r %%i in (*.exe) do @echo %%i
pause
參數不一樣了,這個命令前面沒加那個C:/也就是搜索路徑,這樣他就會以當前文件夾為搜索路徑,比方你這
個BAT你把他防災d:/test文件夾下運行,那么他就會把D:/test文件夾和他以下的子文件夾的所有EXE文件列出
來!!!
/L
迭代數值范圍
使用迭代變量設置起始值 (Start#),然后逐步運行一組范圍的值,直到該值超過所設置的終止值 (End#)
。/L 將通過對 Start# 與 End# 進行比較來運行迭代變量。假設 Start# 小於 End#,就會運行該命令。
假設迭代變量超過 End#,則命令解釋程序退出此循環。還能夠使用負的 Step# 以遞減數值的方式逐步執
行此范圍內的值。比如,(1,1,5) 生成序列 1 2 3 4 5,而 (5,-1,1) 則生成序列 (5 4 3 2 1)。語法是:
系統幫助的格式:for /L %% Variable in (Start#,Step#,End#) do Command
比如:
@echo off
for /l %%i in (1,1,5) do @echo %%i
pause
保存運行看效果,他會打印從1 2 3 4 5 這樣5個數字
(1,1,5)這個參數也就是表示從1開始每次加1直到5終止!
再看這個樣例
@echo off
for /l %%i in (1,1,5) do start cmd
pause
運行后是不是嚇了一跳,怎么多了5個CMD窗體,呵呵!假設把那個 (1,1,5)改成 (1,1,65535)會有什么結果,
我先告訴大家,會打開65535個CMD窗體....這么多你不死機算你強!
當然我們也能夠把那個start cmd改成md %%i 這樣就會建立指定個文件夾了!!!名字為1-65535
看完這個被我賦予破壞性質的參數后,我們來看最后一個參數
/f
含有/F的for具體說明
含有/F的for有非常大的用處,在批處理中使用的最多,使用方法例如以下:
格式:
FOR /F ["options"] %%i IN (file) DO command
FOR /F ["options"] %%i IN ("string") DO command
FOR /F ["options"] %%i IN ('command') DO command
這個可能是最經常使用的,也是最強的命令,主要用來處理文件和一些命令的輸出結果。
file代表一個或多個文件
string 代表字符串
command代表命令
["options"] 可選
對於FOR /F %%i IN (file) DO command
file為文件名稱,依照官方的說法是,for會依次將file中的文件打開,而且在進行到下一個文件之前將每一個文件讀取到內存,依照每一行分成一個一個的元素,忽略空白的行,看個樣例。
假如文件a.txt中有例如以下內容:
第1行第1列 第1行第2列 第1行第3列
第2行第1列 第2行第2列 第2行第3列
第3行第1列 第3行第2列 第3行第3列
你想顯示a.txt中的內容,會用什么命令呢?當然是type,type a.txt
for也能夠完畢相同的命令:
for /f %%i in (a.txt) do echo %%i
還是先從括號運行,由於含有參數/f,所以for會先打開a.txt,然后讀出a.txt里面的所有內容,把它作為一個集合,而且以每一行作為一個元素,所以會產生這種集合,
{“第1行第1列 第1行第2列 第1行第3列”, //第一個元素
“第2行第1列 第2行第2列 第2行第3列”, //第二個元素
“第3行第1列 第3行第2列 第3行第3列”} //第三個元素
集合中僅僅有3個元素,相同用%%i依次取代每一個元素,然后運行do后面的命令。
具體過程:
用%%i取代“第1行第1列 第1行第2列 第1行第3列”,運行do后面的echo %%i,顯示“第1行第1列 第1行第2列 第1行第3列”,
用%%i取代“第2行第1列 第2行第2列 第2行第3列”,運行echo %%i,顯示“第2行第1列 第2行第2列 第2行第3列”,
依次,直到每一個元素都取代完為止。
為了加強理解/f的作用,請運行一下兩個命令,對照就可以明確:
for /f %%i in (a.txt) do echo %%i //這個會顯示a.txt里面的內容,由於/f的作用,會讀出a.txt中
的內容。
for %%i in (a.txt) do echo %%i //而這個僅僅會顯示a.txt這個名字,並不會讀取當中的內容。
通過上面的學習,我們發現for /f會默認以每一行來作為一個元素,可是假設我們還想把每一行再分解更小的內容,該怎么辦呢?不用操心,for命令還為我們提供了更具體的參數,使我們將每一行分為更小的元素成為可能。
它們就是:delims和tokens
delims 用來告訴for每一行應該拿什么作為分隔符,默認的分隔符是空格和tab鍵
比方,還是上面的文件,我們運行以下的命令:
for /f "delims= " %%i in (a.txt) do echo %%i
顯示的結果是:
第1行第1列
第2行第1列
第3行第1列
為什么是這種呢。由於這里有了delims這個參數,=后面有一個空格,意思是再將每一個元素以空格切割,默認是僅僅取切割之后的第一個元素。
運行過程是:
將第一個元素“第1行第1列 第1行第2列 第1行第3列”分成三個元素:“第1行第1列” “第1行第2列” “第1行第3列”,它默認僅僅取第一個,即“第1行第1列”,然后運行do后面的命令,依次類推。
可是這樣還是有局限的,假設我們想要每一行的第二列元素,那又怎樣呢?
這時候,tokens跳出來說,我能做到。
它的作用就是當你通過delims將每一行分為更小的元素時,由它來控制要取哪一個或哪幾個。
還是上面的樣例,運行例如以下命令:
for /f "tokens=2 delims= " %%i in (a.txt) do echo %%i
運行結果:
第1行第2列
第2行第2列
第3行第2列
假設要顯示第三列,那就換成tokens=3。
同一時候tokens支持通配符*,以及限定范圍。
假設要顯示第二列和第三列,則換成tokens=2,3或tokens=2-3,假設還有很多其它的則為:tokens=2-10之類的。
此時的命令為:
for /f "tokens=2,3 delims= " %%i in (a.txt) do echo %%i %%j
怎么多出一個%%j?
這是由於你的tokens后面要取每一行的兩列,用%%i來替換第二列,用%%j來替換第三列。
而且必須是依照英文字母順序排列的,%%j不能換成%%k,由於i后面是j
運行結果為:
第1行第2列 第1行第3列
第2行第2列 第2行第3列
第3行第2列 第3行第3列
對以通配符*,就是把這一行所有或者這一行的剩余部分當作一個元素了。
比方:
for /f "tokens=* delims= " %%i in (a.txt) do echo %%i
運行結果為:
第1行第1列 第1行第2列 第1行第3列
第2行第1列 第2行第2列 第2行第3列
第3行第1列 第3行第2列 第3行第3列
事實上就跟for /f %%i in (a.txt) do echo %%i的運行結果是一樣的。
再如:
for /f "tokens=2,* delims= " %%i in (a.txt) do echo %%i %%j
運行結果為:
第1行第2列 第1行第3列
第2行第2列 第2行第3列
第3行第2列 第3行第3列
用%%i取代第二列,用%%j取代剩余的所有
最后還有skip合eol,這倆個簡單,skip就是要忽略文件的前多少行,而eol用來指定當一行以什么符號開始時,就忽略它。
比方:
for /f "skip=2 tokens=*" %%i in (a.txt) do echo %%i
結果為:
第3行第1列 第3行第2列 第3行第3列
用skip來告訴for跳過前兩行。
假設不加tokens=*的話,運行結果為:
第3行第1列
不知道怎么回事。
再如,當a.txt內容變成:
.第1行第1列 第1行第2列 第1行第3列
.第2行第1列 第2行第2列 第2行第3列
第3行第1列 第3行第2列 第3行第3列
運行for /f "eol=. tokens=*" %%i in (a.txt) do echo %%i結果是:
第3行第1列 第3行第2列 第3行第3列
用eol來告訴for忽略以“.”開頭的行。
相同也必須加tokens=*,否則僅僅會顯示“第3行第1列
終極dos批處理循環命令具體解釋
格式:FOR [參數] %%變量名 IN (相關文件或命令) DO 運行的命令
作用:對一個或一組文件,字符串或命令結果中的每個對象運行特定命令,達到我們想要的結果。
注意:在批處理文件里使用 FOR 命令時,指定變量請使用 %%variable,而不要用 %variable。變量名稱是區分大寫和小寫的,所以 %i 不同於 %I.
關於:for命令能夠帶參數或不帶參數,帶參數時支持以下參數:/d /l /r /f
以下分別解釋一下
===
零:無參數時:
---
FOR %variable IN (set) DO command [command-parameters]
%variable 指定一個單一字母可替換的參數。
(set) 指定一個或一組文件。能夠使用通配符。
command 指定對每一個文件運行的命令。
command-parameters
為特定命令指定參數或命令行開關。
TTT演示樣例:
for %%i in (t*.*) do echo %%i --顯示當前文件夾下與t*.*相匹配的文件(僅僅顯示文件名稱,不顯示路徑)
for %%i in (d:/mydocuments/*.doc) do @echo %%i --顯示d:/mydocuments/文件夾下與*.doc相匹配的文件
===
一、參數 /d (參數僅僅能顯示當前文件夾下的文件夾名字)
---
格式:FOR /D %variable IN (set) DO command [command-parameters]
這個參數主要用於文件夾搜索,不會搜索文件,/D 參數僅僅能顯示當前文件夾下的文件夾名字。(TTT特別說明:僅僅會搜索指定文件夾下的文件夾,不會搜索再下一級的文件夾。)
TTT演示樣例:
for /d %%i in (c:/*) do echo %%i --顯示c盤根文件夾下的全部文件夾
for /d %%i in (???) do echo %%i --顯示當前文件夾下名字僅僅有1-3個字母的文件夾
===
二、參數 /R (搜索指定路徑及全部子文件夾中與set相符合的全部文件)
---
格式:FOR /R [[drive:]path] %variable IN (set) DO command [command-parameters]
此命令會搜索指定路徑及全部子文件夾中與set相符合的全部文件,注意是指定路徑及全部子文件夾。
1、set中的文件名稱假設含有通配符(?或*),則列舉/R參數指定的文件夾及其以下的所用子文件夾中與set相符合的全部文件,無相符文件的文件夾則不列舉。
2、假設set中為詳細文件名稱,不含通配符,則枚舉該文件夾樹(即列舉該文件夾及其以下的全部子文件夾)(並在后面加上詳細的文件名稱),而無論set中的指定文件是否存在。
例:for /r c:/ %%i in (*.exe) do echo %%i --把C盤根文件夾,和每一個文件夾的子文件夾以下全部的EXE文件都列出來了!!!!
TTT演示樣例:
for /r c:/ %%i in (boot.ini) do echo %%i --枚舉了c盤全部文件夾
for /r d:/backup %%i in (1) do echo %%i --枚舉d/backup文件夾
for /r c:/ %%i in (boot.ini) do if exist %%i echo %%i --非常好的搜索命令,列舉boot.ini存在的文件夾
===
三、參數 /L (該集表示以增量形式從開始到結束的一個數字序列。能夠使用負的 Step)
---
格式:FOR /L %variable IN (start,step,end) DO command [command-parameters]
該集表示以增量形式從開始到結束的一個數字序列。能夠使用負的 Step
TTT演示樣例:
for /l %%i in (1,1,5) do @echo %%i --輸出1 2 3 4 5
for /l %%i in (1,2,10) do @echo %%i --輸出1,3,5,7,9
for /l %%i in (100,-20,1) do @echo %%i --輸出100,80,60,40,20
for /l %%i in (1,1,5) do start cmd --打開5個CMD窗體
for /l %%i in (1,1,5) do md %%i --建立從1~5共5個目錄
for /l %%i in (1,1,5) do rd /q %%i --刪除從1~5共5個目錄
四、參數 /F (使用文件解析來處理命令輸出、字符串及文件內容。)
---
這個參數是最難的,參數又多,先簡單的解釋一下:for命令帶這個參數能夠分析文件內容,字符串內容或某一命令輸出的結果,並通過設置option得我們想要的結果。
下面是某高手的解釋,感覺有點太專業了,自覺得不太easy理解,也列一下:
[迭代及文件解析--使用文件解析來處理命令輸出、字符串及文件內容。使用迭代變量定義要檢查的內容或字符串,並使用各種options選項進一步改動解析方式。使用options令牌選項指定哪些令牌應該作為迭代變量傳遞。
請注意:在沒有使用令牌選項時,/F 將僅僅檢查第一個令牌。文件解析過程包含讀取輸出、字符串或文件內容,將其分成獨立的文本行以及再將每行解析成零個或很多其它個令牌。然后通過設置為令牌的迭代變量值,調用 for 循環。
默認情況下,/F 傳遞每一個文件每一行的第一個空白分隔符號。跳過空行。]
+++
格式:
FOR /F ["options"] %variable IN (file-set) DO command [command-parameters]
FOR /F ["options"] %variable IN ("string") DO command [command-parameters]
FOR /F ["options"] %variable IN ('command') DO command [command-parameters]
或者,假設有 usebackq 選項:
FOR /F ["options"] %variable IN (file-set) DO command [command-parameters]
FOR /F ["options"] %variable IN ("string") DO command [command-parameters]
FOR /F ["options"] %variable IN ('command') DO command [command-parameters]
TTT說明:以上是WinXP系統中的幫助內容,你能夠注意到,兩者全然同樣,這事實上是系統的錯誤,第二段“假設有 usebackq 選項:”應該下面的內容:
FOR /F ["options"] %variable IN ("file-set") DO command [command-parameters]
FOR /F ["options"] %variable IN ('string') DO command [command-parameters]
FOR /F ["options"] %variable IN (`command`) DO command [command-parameters] --(`command`中的引號為反引號,是鍵盤上數字1左面的那個鍵)
+++
(TTT說明:以下是具體的解釋,大部分是系統中的幫助內容,也有些錯誤(怪不得for命令這么難學),已經被我糾正了。)
1) OPTIONkeyword具體解釋:
eol=c:指一個行凝視字符的結尾(就一個)。比如:eol=; --忽略以分號打頭的那些行;
skip=n:指在文件開始時忽略的行數。比如:skip=2 --忽略2行;
delims=xxx:指分隔符集。這個替換了空格和跳格鍵的默認分隔符集。比如:[delims=, ] --指定用逗號,空格對字符串進行分隔。
tokens=x,y,m-n:指每行的哪一個符號被傳遞到每一個迭代的 for 本身。這會導致額外變量名稱的分配。m-n格式為一個范圍。通過 nth 符號指定 mth。假設符號字符串中的最后一個字符是星號,那么額外的變量將在最后一個符號解析之后分配並接受行的保留文本。比如:tokens=2,3* --將每行中的第二個和第三個符號傳遞給 for 程序體;tokens=2,3* ... i% --將會把取到的第二個字符串賦給i%,第三個賦給j%,剩下的賦給k%。
關於usebackq,不同版本號的系統提示不同的幫助,只是都有助於理解,所以都摘抄例如以下:
(1),usebackq:使用后引號(鍵盤上數字1左面的那個鍵`)。未使用參數usebackq時:file-set表示文件,不能加引號,所以不能含有空格;加雙引號表示字符串,即"string";加單引號表示運行命令,即'command'。使用參數usebackq時:file-set和"file-set"都表示文件,當文件路徑或名稱中有空格時,就能夠用雙引號括起來;單引號表示字符串,即'string';后引號表示命令運行,即`command`。(此段是WinXP系統中的幫助)
(2),usebackq:指定新語法已在下類情況中使用:在作為命令運行一個后引號的字符串;而且一個單引號字符為文字字符串命令;並同意在filenameset中使用雙引號擴起文件名稱稱。
以上兩條結合着看,事實上已經能夠明確了,我再說明一下:
事實上這個參數的目的就是為了處理帶有空格的文件名稱。假設您要處理的文件名稱和路徑中含有空格,假設直接使用,會提示找不到文件。假設你用雙引號將文件名稱和路徑括起來。這時候將作為字符串處理,而不是作為文件了。為了應對這樣的情況,所以才添加了這個“usebackq”參數。假設使用了這個參數,對於括號里的加雙引號的集合,系統就能夠覺得是文件了;真正的字符串要加單引號;命令要加反引號。
2) file-set 為一個或多個文件名稱。繼續到 file-set 中的下一個文件之前,每份文件都已被打開、讀取並經過處理。處理包含讀取文件,將其分成一行行的文字,然后將每行解析成零或很多其它的符號。然后用已找到的符號字符串變量值調用 For 循環。以默認方式,/F 通過每一個文件的每一行中分開的第一個空白符號。跳過空白行。您可通過指定可選 "options"參數替代默認解析操作。這個帶引號的字符串包含一個或多個指定不同解析選項的keyword。
3) %i:專門在 for 語句中得到說明,%j 和 %k 是通過tokens= 選項專門得到說明的。您能夠通過 tokens= 一行指定最多 26 個符號,僅僅要不試圖說明一個高於字母 'z' 或'Z' 的變量。請記住,FOR 變量是單一字母、分大寫和小寫和全局的;並且,同一時候不能有 52 個以上都在使用中。
(TTT補充說明:
一般在tokens后僅僅指定第一個參數,如%%i或%%a,在后面使用第二個及兩個以上的參數,自己主動按順序往下排就可以。如前面指定的是%%a,后面則用%%b代表第二個結果,%%c代表第 三個結果。。。測試了一下tokens后指定多個變量名,沒有測試成功,應該是不能夠的。所以token后僅僅能跟要使用的第一個變量名
假設使用的變量名超過了%z或%Z,就無法使用了,以前以為會循環過來:如%%z后能夠使用%%a或%%A,但經測試,這是不能夠的。
如:for /f "tokens=1,2,3* delims=-, " %%y in ("aa bb,cc-dd ee") do echo %%y %%z %%A %%a --僅僅會輸出前兩個字符串,后面的兩個變量是無效的。)
+++
下面是系統提供的范例:
FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do @echo %i %j %k --
說明:會分析 myfile.txt 中的每一行,
eol=; --忽略以分號打頭的那些行;
tokens=2,3* --將每行中的第二個和第三個符號傳遞給 for 程序體;
delims= , --用逗號和/或空格定界符號。
%i --這個 for 程序體的語句引用 %i 來取得取得的首個字符串(本例中為第二個符號),引用 %j 來取得第二個字符串(本例中為第三個符號)引用 %k來取得第三個符號后的全部剩余符號。
(TTT說明:上述樣例和說明中明顯的錯誤,%i應該換為%%i(幫助中有明白的說明:指定變量請使用 %%variable,而不要用 %variable,誤導)
+++
TTT:以下列我做的幾個樣例:
1,分析文件的樣例
FOR /F "eol=; tokens=1,2* delims=,- " %%i in (d:/test.txt) do echo %%i %%j %%k
2,分析字符串的樣例:
for /f "tokens=1,2,3* delims=-, " %%i in ("aa bb,cc-dd ee") do echo %%i %%j %%k %%l
3,分析命令輸出的樣例:
FOR /F "tokens=1* delims==" %%i IN ('set') DO @echo [%%i----%%j]
假設使用了usebackq參數后,命令例如以下,結果與上面的全然同樣。
1,分析文件的樣例
FOR /F "usebackq eol=; tokens=1,2* delims=,- " %%i in ("d:/test.txt") do echo %%i %%j %%k
2,分析字符串的樣例:
for /f "usebackq tokens=1,2,3* delims=-, " %%i in ('aa bb,cc-dd ee') do echo %%i %%j %%k %%l
3,分析命令輸出的樣例:(會枚舉當前環境中的環境變量名稱和值。)
FOR /F "usebackq tokens=1* delims==" %%i IN (`set`) DO @echo [%%i----%%j]
結果大家能夠試一下,非常easy就明確的。
===
FOR命令中的變量
---
FOR 變量參照的替換已被增強。您如今能夠使用下列選項語法:
~I - 刪除不論什么引號("),擴充 %I
%~fI - 將 %I 擴充到一個全然合格的路徑名
%~dI - 僅將 %I 擴充到一個驅動器號
%~pI - 僅將 %I 擴充到一個路徑
%~nI - 僅將 %I 擴充到一個文件名稱
%~xI - 僅將 %I 擴充到一個文件擴展名
%~sI - 擴充的路徑僅僅含有短名
%~aI - 將 %I 擴充到文件的文件屬性
%~tI - 將 %I 擴充到文件的日期/時間
%~zI - 將 %I 擴充到文件的大小
%~$PATH:I - 查找列在路徑環境變量的文件夾(TTT提示:是環境變量path的文件夾),並將 %I 擴充到找到的第一個全然合格的名稱。假設環境變量名未被定義,或者沒有找到文件,此組合鍵會擴充到空字符串
此外,還能夠組合修飾符來得到多重結果:
%~dpI - 僅將 %I 擴充到一個驅動器號和路徑
%~nxI - 僅將 %I 擴充到一個文件名稱和擴展名
%~fsI - 僅將 %I 擴充到一個帶有短名的完整路徑名
%~dp$PATH:i - 查找列在路徑環境變量的文件夾,並將 %I 擴充到找到的第一個驅動器號和路徑。
%~ftzaI - 將 %I 擴充到相似輸出線路的 DIR
在以上樣例中,%I 和 PATH 可用其它有效數值取代。%~ 語法用一個有效的 FOR 變量名終止。選取相似 %I 的大寫變量名比較易讀,並且避免與不分大寫和小寫的組合鍵混淆。
(以上是系統幫助的內容)
我們能夠看到每行都有一個大寫字母"I",這個I事實上就是我們在FOR帶入的變量,比如:
FOR /F "usebackq eol=; tokens=1,2* delims=,- " %%x in ("d:/test.txt") do echo %%x %%y %%z
這里我們就要把那個x,y,z改成%~fx,%~fy,%~fz。
+++
TTT特例:下面是我依據以上說明作的一個綜合的樣例,能夠直接拷貝到記事本里,保存為bat格式(c盤下任一文件夾),執行后,能夠直觀的看到擴展后的效果。
@echo off
echo ---顯示"dir c:/boot.ini /b /ah"
for /f "delims==" %%i in ('dir c:/boot.ini /b /ah') do echo 不擴展變量 %%i
for /f "delims==" %%i in ('dir c:/boot.ini /b /ah') do echo 擴展變量到~fI %%~fi --擴充到一個全然合格的路徑名
for /f "delims==" %%i in ('dir c:/boot.ini /b /ah') do echo 擴展變量到~dI %%~di --僅將變量擴充到一個驅動器號
for /f "delims==" %%i in ('dir c:/boot.ini /b /ah') do echo 擴展變量到~pI %%~pi --僅將變量擴充到一個路徑
for /f "delims==" %%i in ('dir c:/boot.ini /b /ah') do echo 擴展變量到~nI %%~ni --僅將變量擴充到一個文件名稱
for /f "delims==" %%i in ('dir c:/boot.ini /b /ah') do echo 擴展變量到~xI %%~xi --僅將變量擴充到一個文件擴展名
for /f "delims==" %%i in ('dir c:/boot.ini /b /ah') do echo 擴展變量到~sI %%~si --擴充的路徑僅僅含有短名
for /f "delims==" %%i in ('dir c:/boot.ini /b /ah') do echo 擴展變量到~aI %%~ai --將變量擴充到文件的文件屬性
for /f "delims==" %%i in ('dir c:/boot.ini /b /ah') do echo 擴展變量到~tI %%~ti --將變量擴充到文件的日期/時間
for /f "delims==" %%i in ('dir c:/boot.ini /b /ah') do echo 擴展變量到~zI %%~zi --將變量擴充到文件的大小
for /f "delims==" %%i in ('dir c:/boot.ini /b /ah') do echo 擴展變量到~$PATH:I %%~$PATH:i --查找列在路徑環境變量的文件夾,並將變量擴充到找到的第一個全然合格的名稱
echo ---下面顯示組合修飾符來得到多重結果---:
for /f "delims==" %%i in ('dir c:/boot.ini /b /ah') do echo 擴展變量到~dpI %%~dpi --僅將變量擴充到一個驅動器號和路徑
for /f "delims==" %%i in ('dir c:/boot.ini /b /ah') do echo 擴展變量到~nxI %%~nxi --僅將變量擴充到一個文件名稱和擴展名
for /f "delims==" %%i in ('dir c:/boot.ini /b /ah') do echo 擴展變量到~fsI %%~fsI --僅將變量擴充到一個帶有短名的完整路徑名
for /f "delims==" %%i in ('dir c:/boot.ini /b /ah') do echo 擴展變量到~dp$PATH:I %%~dp$PATH:i --查找列在路徑環境變量的文件夾,並將變量擴充到找到的第一個驅動器號和路徑
for /f "delims==" %%i in ('dir c:/boot.ini /b /ah') do echo 擴展變量到~ftzaI %%~ftzai --將變量擴充到相似輸出線路的DIR
echo.
echo ---顯示"dir C:/WINDOWS/system32/notepad.exe /b"
for /f "delims==" %%i in ('dir C:/WINDOWS/system32/notepad.exe /b') do echo 不擴展變量 %%i
for /f "delims==" %%i in ('dir C:/WINDOWS/system32/notepad.exe /b') do echo 擴展變量到~fI %%~fi --擴充到一個全然合格的路徑名
for /f "delims==" %%i in ('dir C:/WINDOWS/system32/notepad.exe /b') do echo 擴展變量到~dI %%~di --僅將變量擴充到一個驅動器號
for /f "delims==" %%i in ('dir C:/WINDOWS/system32/notepad.exe /b') do echo 擴展變量到~pI %%~pi --僅將變量擴充到一個路徑
for /f "delims==" %%i in ('dir C:/WINDOWS/system32/notepad.exe /b') do echo 擴展變量到~nI %%~ni --僅將變量擴充到一個文件名稱
for /f "delims==" %%i in ('dir C:/WINDOWS/system32/notepad.exe /b') do echo 擴展變量到~xI %%~xi --僅將變量擴充到一個文件擴展名
for /f "delims==" %%i in ('dir C:/WINDOWS/system32/notepad.exe /b') do echo 擴展變量到~sI %%~si --擴充的路徑僅僅含有短名
for /f "delims==" %%i in ('dir C:/WINDOWS/system32/notepad.exe /b') do echo 擴展變量到~aI %%~ai --將變量擴充到文件的文件屬性
for /f "delims==" %%i in ('dir C:/WINDOWS/system32/notepad.exe /b') do echo 擴展變量到~tI %%~ti --將變量擴充到文件的日期/時間
for /f "delims==" %%i in ('dir C:/WINDOWS/system32/notepad.exe /b') do echo 擴展變量到~zI %%~zi --將變量擴充到文件的大小
for /f "delims==" %%i in ('dir C:/WINDOWS/system32/notepad.exe /b') do echo 擴展變量到~$PATH:I %%~$PATH:i --查找列在路徑環境變量的文件夾,並將變量擴充到找到的第一個全然合格的名稱
echo ---下面顯示組合修飾符來得到多重結果---:
for /f "delims==" %%i in ('dir C:/WINDOWS/system32/notepad.exe /b') do echo 擴展變量到~dpI %%~dpi --僅將變量擴充到一個驅動器號和路徑
for /f "delims==" %%i in ('dir C:/WINDOWS/system32/notepad.exe /b') do echo 擴展變量到~nxI %%~nxi --僅將變量擴充到一個文件名稱和擴展名
for /f "delims==" %%i in ('dir C:/WINDOWS/system32/notepad.exe /b') do echo 擴展變量到~fsI %%~fsI --僅將變量擴充到一個帶有短名的完整路徑名
for /f "delims==" %%i in ('dir C:/WINDOWS/system32/notepad.exe /b') do echo 擴展變量到~dp$PATH:I %%~dp$PATH:i --查找列在路徑環境變量的文件夾,並將變量擴充到找到的第一個驅動器號和路徑
for /f "delims==" %%i in ('dir C:/WINDOWS/system32/notepad.exe /b') do echo 擴展變量到~ftzaI %%~ftzai --將變量擴充到相似輸出線路的DIR
Pause
TTT說明:
1,以上命令中,%%~fsI無法顯示,預計是系統錯誤,由於%%~fI是擴充到一個全然合格的路徑名,%%~sI僅僅含有短文件名稱,本身是相互矛盾的,所以出錯。不知是系統的錯誤還是在考我們~~
2,以上命令假設保存在別的盤中,無法顯示正確的驅動器和路徑。
3,假設想要%%~dp$PATH:i正常顯示,要保證環境變量path中確實有這個路徑:C:/WINDOWS/system32。
以下依次說明一下:
+++
一、 ~I - 刪除不論什么引號("),擴展 %I
---
這個變量的作用就如他的說明,刪除引號!
刪除引號規則例如以下(BAT兄補充!):
1、若字符串首尾同一時候存在引號,則刪除首尾的引號;
2、若字符串尾不存在引號,則刪除字符串首的引號;
3、假設字符串中間存在引號,或者僅僅在尾部存在引號,則不刪除。
龍卷風補充:無頭不刪,有頭連尾刪。
我們來看這個樣例,首先建立暫時文件temp.txt,內容例如以下
"1111
"2222"
3333"
"4444"44
"55"55"55
也可建立個BAT文件代碼例如以下:
@echo off
echo ^"1111>temp.txt
echo "2222">>temp.txt
echo 3333^">>temp.txt
echo "4444"44>>temp.txt
echo ^"55"55"55>>temp.txt
rem 上面建立暫時文件,注意不成對的引號要加轉義字符^,重定向符號前不要留空格
FOR /F "delims=" %%i IN (temp.txt) DO echo %%~i
pause
del temp.txt
運行后,我們看CMD的回顯例如以下:
1111 #字符串前的引號被刪除了
2222 #字符串首尾的引號都被刪除了
3333" #字符串前無引號,后面的引號保留
4444"44 #字符串前面的引號刪除了,而中間的引號保留
55"55"55 #字符串前面的引號刪除了,而中間的引號保留
請按隨意鍵繼續. . .
結果和之前temp.txt中的內容對照一下,我們會發現第1、2、5行的引號都消失了,這就是刪除引號~i的作用了!
+++
二、 %~fI - 將 %I 擴展到一個全然合格的路徑名
演示樣例:
把代碼保存放在隨便哪個地方,我這里就放桌面吧.
FOR /F "delims==" %%i IN ('dir /b') DO @echo %%~fi
pause
運行后顯示內容例如以下
C:/Documents and Settings/Administrator/桌面/test.bat
C:/Documents and Settings/Administrator/桌面/test.vbs
當我把代碼中的 %%~fi直接改成%%i
FOR /F "delims==" %%i IN ('dir /b') DO @echo %%i
pause
運行后就會顯示下面內容:
test.bat
test.vbs
通過對照,我們非常easy就看出沒有路徑了,這就是"將 %I 擴展到一個全然合格的路徑名"的作用,也就是假設%i變量的內容是一個文件名稱的話,他就會把這個文件所在的絕對路徑打印出來,而不僅僅單單打印一個文件名稱,自己動手動實驗下就知道了!
+++
三、 %~dI - 僅將 %I 擴展到一個驅動器號
看樣例:
代碼例如以下,我還是放到桌面運行!
FOR /F "delims==" %%i IN ('dir /b') DO @echo %%~di
pause
運行后我CMD里顯演示樣例如以下
C:
C:
我桌面就兩個文件test.bat,test.vbs,%%~di作用是,假設變量%%i的內容是一個文件或者文件夾名,他就會把他這文件或者文件夾所在的盤符號打印出來!
+++
四、 %~pI - 僅將 %I 擴展到一個路徑
這個使用方法和上面一樣,他僅僅打印路徑不打印文件名稱字
FOR /F "delims==" %%i IN ('dir /b') DO @echo %%~pi
pause
我就不打結果了,大家自己復制代碼看結果吧,以下幾個都是這么個使用方法,代碼給出來,大家自己看結果吧!
+++
五、 %~nI - 僅將 %I 擴展到一個文件名稱
僅僅打印文件名稱字
FOR /F "delims==" %%i IN ('dir /b') DO @echo %%~ni
pause
+++
六、 %~xI - 僅將 %I 擴展到一個文件擴展名
僅僅打印文件的擴展名
FOR /F "delims==" %%i IN ('dir /b') DO @echo %%~xi
pause
+++
七、 %~sI - 擴展的路徑僅僅含有短名
打印絕對短文件名稱
FOR /F "delims==" %%i IN ('dir /b') DO @echo %%~si
pause
+++
八、 %~aI - 將 %I 擴展到文件的文件屬性
打印文件的屬性
FOR /F "delims==" %%i IN ('dir /b') DO @echo %%~ai
pause
+++
九、 %~tI - 將 %I 擴展到文件的日期/時間
打印文件建立的日期
FOR /F "delims==" %%i IN ('dir /b') DO @echo %%~ti
pause
+++
十、 %~zI - 將 %I 擴展到文件的大小
打印文件的大小
FOR /F "delims==" %%i IN ('dir /b') DO @echo %%~zi
pause
龍卷風補充:上面樣例中的"delims=="能夠改為"delims=",即不要分隔符
+++
十一、 %~$PATH:I - 查找列在路徑環境變量的文件夾,並將 %I 擴展到找到的第一個全然合格的名稱。假設環境變量名未被定義,或者沒有找到文件,此組合鍵會擴展到空字符串
這是最后一個,和上面那些都不一樣,我單獨說說!
然后在把這些代碼保存為批處理,放在桌面。
@echo off
FOR /F "delims=" %%i IN (“notepad.exe”) DO echo %%~$PATH:i
pause
龍卷風補充:上面代碼顯示結果為C:/WINDOWS/system32/notepad.exe
他的意思就在PATH變量里指定的路徑里搜索notepad.exe文件,假設有notepad.exe則會把他所在絕對路徑打印出來,沒有就打印一個錯誤!
(TTT說明,保存到桌面上,執行顯示結果為:系統找不到文件 “notepad.exe”。查看環境變量path中確實有這個路徑,不明原因!后來發現了,原來是中文引號的原因。
上面的命令應該寫成:
FOR /F "delims=" %%i IN ("notepad.exe") DO echo %%~$PATH:i
)
最后發一個用批處理做一五子棋游戲:
@echo off&setlocal enabledelayedexpansion
mode con: lines=43 cols=110
set li39= A B C D E F G H I J K L M N O P Q R S
set li0= ┌─────────────────────────────────────┐
set li1=A│┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐│A
set var=1
for %%a in (!li39:~5^,-1!) do (set/a var+=2&set li!var!=%%a│├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤│%%a)
for /l %%a in (2,2,36) do (set li%%a= ││ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ││)
set li37=S│└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘│S
set li38= └─────────────────────────────────────┘
set str=a b c d e f g h i j k l m n o p q r s
for %%a in (%str%) do (set/a .+=1,%%a=.&set z!.!=%%a)
set li5=!li5! 五 棋 子 人 機 對 戰
set li7=!li7! 批 處 理
set li10=!li10! 電 腦 水 平 中 等
set li31=!li31! 由 netbenton 編寫完畢
set li33=!li33! 棋盤設計參照了 batman
title 批處理五子棋
set str=###################
set .=0
for /l %%a in (1,1,19) do (
set he%%a=!str!&set sh%%a=!str!
for /l %%b in (1,1,19) do set [%%a.%%b=0
)
set .=33
for /l %%a in (5,1,19) do (
set pi%%a=!str:~,%%a!&set ni%%a=!str:~,%%a!
set pi!.!=!str:~,%%a!&set ni!.!=!str:~,%%a!
set/a .-=1
)
set ●=○&set ○=●
set zhi=●
set say=say
::設置電腦IQ
set idea=@@@@#.1 #@@@@.5 @#@@@.4 @@@#@.2 @@#@@.3 vs0 $$$$#.1 #$$$$.5 $$#$$.3 $#$$$.4 $$$#$.2 vs1 #@@@##.2 ##@@@#.5 #@@#@#.3 #@#@@#.4 vs2 #@##@@#.4-5 #@@##@#.4-3 #@#@@.3-5 @#@@#.4-1 #@@@##.2-W-1 ##@@@#.5-W-6 vs3
set idea=!idea! ##@@@.4-W-5 @@@##.2-W-1 @##@@#.4-5 #@##@@.3-4 #@#@#@.4-2 @#@#@#.3-5 vs4 #$$#$#.3-W-6-1 #$#$$#.4-W-1-6 ##$$$#.5-W-1-6 #$$$##.2-W-1-6 vs5 ##@@##.2-5-W-6-1 #@#@#.3-w-1-5 ##$$$.W-4-5 $$$##.W-2-1 $$##$.W-2-3 $##$$.W-3-4 $#$$#.W-4-1 $#$#$.W-4-2 #$$#$.W-2-5 ##$$#.W-4-W-1-5 #$$##.W-2-W-1-5 #$#$#.W-3-W-1-5 #$##$#.W-3-4
set idea=!idea! vs7 #$$$#.1-5 @@###.4-3 ###@@.3-4 ###@###.3-5-W-2-6-W-1-7 vs8 ###$###.3-5 vs9 @####.4 ####@.2 #$###.3 ###$#.3
set idea=!idea! ###@#.3 #@###.3 $####.3 ####$.3 $$###.3 ###$$.3 $#$##.2 ##$#$.4 #$##$.3 $##$#.3 $###$.3 vs10
set iqam=1000000000
:restart
(
setlocal enabledelayedexpansion
for /l %%a in (0,1,39) do (echo !li%%a!)
set li39=!li39! reboot又一次開始,exit退出。
set li37=!li37! back 悔棋
set /p var=選擇誰先下[ W,玩家 D,電腦 Q,退出 ]:
if /i "!var!" equ "Q" goto :quit
if /i "!var!" equ "D" (set onez=○&set towz=●&set hou=☆) else (set onez=●&set towz=○&set hou=★)
set a!onez!=電腦&set a!towz!=玩家
)
(
set ttr=!idea=%onez%!&set ttr=!ttr=%towz%!
set idea=
for %%a in (!ttr!) do (
for /f "tokens=1,2 delims=." %%b in ("%%a") do (set %%b=%%c&set idea=!idea! %%b)
)
set ttr=
set li27=!li27! !onez! !a%onez%!
set li25=!li25! !towz! !a%towz%!
set/a pos=10,poh=10&goto :getok
)
:loop
(if %zhi% equ %onez% goto :men
set .=
setlocal enabledelayedexpansion
for %%a in (!idea!) do (
set str=%%a
if "!str:~,2!" neq "vs" (
for %%b in (he sh) do (
set all=!%%b1!!%%b2!!%%b3!!%%b4!!%%b5!!%%b6!!%%b7!!%%b8!!%%b9!!%%b10!!%%b11!!%%b12!!%%b13!!%%b14!!%%b15!!%%b16!!%%b17!!%%b18!!%%b19!
if "!all:%%a=!" neq "!all!" (
for /l %%c in (1,1,19) do (
if "!%%b%%c:%%a=!" neq "!%%b%%c!" set/a .+=1&set put!.!=%%b %%c.%%a.!iqam!
)
) )
for %%b in (pi ni) do (
set all=!%%b5!!%%b6!!%%b7!!%%b8!!%%b9!!%%b10!!%%b11!!%%b12!!%%b13!!%%b14!!%%b15!!%%b16!!%%b17!!%%b18!!%%b19!!%%b20!!%%b21!!%%b22!!%%b23!!%%b24!!%%b25!!%%b26!!%%b27!!%%b28!!%%b29!!%%b30!!%%b31!!%%b32!!%%b33!
if "!all:%%a=!" neq "!all!" (
for /l %%c in (5,1,33) do (
if "!%%b%%c:%%a=!" neq "!%%b%%c!" set/a .+=1&set put!.!=%%b %%c.%%a.!iqam!
)
) )
) else (
set/a "iqam=(iqam+1)/8"
if %%a equ vs8 if defined . goto :get
if %%a equ vs9 if defined . goto :get
)
))
if defined . (goto :get)
echo. 已經和棋了
pause
endlocal&goto :restart
:men
(
set/a .=lips-1&for /f "tokens=1-3" %%b in ("li!liph! !lips! !.!") do (set %%b=!%%b:~0,%%d!%hou%!%%b:~%%c!)
set li38=!li38![%悔:~,24%]
cls
for /l %%a in (0,1,39) do (echo !li%%a!)
for /f "tokens=1-3" %%b in ("li!liph! !lips! !.!") do (set %%b=!%%b:~0,%%d!%zhi%!%%b:~%%c!)
set li38=%li38%
set /p user=!say:say=%error%! [列前,行后]:
if "!user!" equ "reboot" endlocal&goto :restart
if "!user!" equ "exit" goto :quit
if "!user!" equ "back" call :悔&goto :men
set/a pos=!user:~0,1!,poh=!user:~1,2!,var=pos-1 2>nul
if not defined [!poh!.!pos! set error=輸入點不存在 &goto :men
)
if "!he%poh%:~%var%,1!" neq "#" set error=該點已經有子 &goto men
goto :getok
:get
set `=
::取最佳的走法
for /l %%z in (!.!,-1,1) do (
for /f "tokens=1,2,3 delims=." %%1 in ("!put%%z!") do (
for /f "tokens=1-4" %%a in ("%%1 %%2") do (
set iqm=%%3
set vara=!%%a%%b:*%%c=!srqponmlkjihgfedcba0
for %%4 in (!%%2:-^=;!) do (
if "%%4" equ "W" (set/a iqm=iqm/5*3) else (
set/a var=!vara:~19,1!+%%4
if "%%a" equ "he" (set/a poh=%%b,pos=20-var)
if "%%a" equ "sh" (set/a poh=20-var,pos=%%b)
if %%b lss 19 (set/a var=%%b-var+1) else (set/a var=38-%%b-var+1)
if "%%a" equ "pi" (if %%b lss 19 (set/a pos=var,poh=%%b-var+1) else (set/a poh=20-var,pos=%%b-19+var))
if "%%a" equ "ni" (if %%b lss 19 (set/a pos=var,poh=19-%%b+var) else (set/a poh=var,pos=%%b-19+var))
if not defined R!pos!R!poh!R set /a `+=1&set ram!`!=R!pos!R!poh!R
set/a R!pos!R!poh!R+=iqm
)
)
)
)
)
set rmk=0
for /l %%a in (1,1,!`!) do (
for %%b in (!ram%%a!) do (
for %%c in (!%%b!) do (
if %%c gtr !rmk! set/a rmk=%%c,.=0
if %%c equ !rmk! set rmz!.!=%%b&set/a .+=1
)
) )
set/a .=!random!%%.
for /f "tokens=1,2 delims=R" %%a in ("!rmz%.%!") do (set/a pos=%%a,poh=%%b)
rem start set r^&echo !.!^&pause^&exit
endlocal&set/a pos=%pos%,poh=%poh%
set say=say !z%pos%!!z%poh%!(%poh%)&set error=電腦最后下在:
:getok
set zhi=!%zhi%!&set win=!zhi!!zhi!!zhi!!zhi!!zhi!
(set/a piph=poh+pos-1,lips=pos*2+1,niph=19+pos-poh,liph=poh*2-1
if !piph! lss 19 (set/a pips=pos) else (set/a pips=20-poh)
if !niph! lss 19 (set/a nips=pos) else (set/a nips=poh)
for %%a in ("li!liph! !lips!" "he!poh! !pos!" "sh!pos! !poh!" "pi!piph! !pips!" "ni!niph! !nips!") do (
for /f "tokens=1,2" %%b in (%%a) do (
set/a .=%%c-1
for %%d in (!.!) do (set %%b=!%%b:~0,%%d!%zhi%!%%b:~%%c!)
if "!%%b:%win%=!" neq "!%%b!" set win=y
)
))
(set/a asc%zhi%+=1
set 悔= !z%pos%!!z%poh%!!悔!
if !win! neq y goto :loop)
for /l %%a in (0,1,39) do (echo !li%%a!)
set/p= !a%zhi%! %zhi%子 第!asc%zhi%!手 !z%pos%!!z%poh%!(%poh%) 勝出 <nul
pause
endlocal&goto :restart
:悔
if not defined 悔 goto :eof
if "!悔:~6,1!" equ "" goto :eof
for %%a in (!悔:~^,6!) do (set str=%%a
set/a poh=!str:~-1!,pos=!str:~,1!
set/a piph=poh+pos-1,niph=19+pos-poh,liph=poh*2-1,lips=pos*2+1
if !piph! lss 19 (set/a pips=pos) else (set/a pips=20-poh)
if !niph! lss 19 (set/a nips=pos) else (set/a nips=poh)
for %%a in ( "he!poh! !pos!" "sh!pos! !poh!" "pi!piph! !pips!" "ni!niph! !nips!") do (
for /f "tokens=1,2" %%b in (%%a) do (
set/a .=%%c-1
for %%d in (!.!) do (set %%b=!%%b:~0,%%d!#!%%b:~%%c!)
)
)
for /f "tokens=1,2" %%b in ("li!liph! !lips!") do (
set/a .=%%c-1
for %%d in (!.!) do (set %%b=!%%b:~0,%%d!┼!%%b:~%%c!)
))
set/a asc%zhi%-=1
set 悔=!悔:~6!
set error=你悔棋,耍賴皮!
if not defined 悔 goto :eof
set/a poh=!悔:~2,1!,pos=!悔:~1,1!,liph=poh*2-1,lips=pos*2+1
set say=say !z%pos%!!z%poh%!(%poh%)
goto :eof
:quit
taskkill /fi "WINDOWTITLE eq 批處理五子棋*" /im cmd.exe