批處理 for詳解



轉自:
http://wenku.baidu.com/link?url=ZpLkHk5AFQCGZhDsSqogUCW77ztY8Ue46RV35KSol1RgFDm-cIzQBYratmMncTf64x2zxgudDLwpfQfdSjnjmc0xpS8GPSQxTyfnCc2E31O


+++
格式: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得我們想要的結果。
以下是某高手的解釋,感覺有點太專業了,自認爲不太容易理解,也列一下:
[迭代及文件解析--使用文件解析來處理命令輸出、字符串及文件內容。使用迭代變量定義要檢查的內容或字符串,並使用各種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) OPTION關鍵字詳解:
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"參數替代默認解析操作。這個帶引號的字符串包括一個或多個指定不同解析選項的關鍵字。

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]
結果大家可以試一下,很容易就明白的。

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
通過對比,我們很容易就看出沒有路徑了,這就是"將 %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 
)


批處理for命令詳解 


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列"


發佈了21 篇原創文章 · 獲贊 46 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章