1. 前言
for是批處理中最複雜,也最強大的關鍵字。熟練掌握for的用法,纔可能理解批處理的強大之處。
2. 基本用法
2.1. 概念
for是對一組文件中的每一個文件執行某個特定命令。
FOR %variable IN (set) DO command [command-parameters]
- %variable, 指定一個單一字母可替換的參數。
- (set) ,指定一個或一組文件,也可以一段文本內容。可以使用通配符。默認以空格,;三種符號分隔開。
- command , 指定對每個文件執行的命令。
- command-parameters ,爲特定命令指定參數或命令行開關。
在批處理程序中使用 for命令時,指定變量請使用 %%variable而不要用 %variable。變量名稱是區分大小寫的,所以 %i 不同於 %I.
2.2. 示例
rem 遍歷c盤的所有文件(不包括文件夾),然後輸出到控制檯
for %%i in (c:\*.*) do @echo %%i
rem 以空格爲分隔符,將a、b、c逐行輸出到控制檯
for %%i in (a b c) do @echo %%i
rem 字符串加""則認爲不分割,%~i不顯示雙引號
for %%i in ("a b c") do @echo %%~i
rem 遍歷所有磁盤,判斷存在的並輸出至控制檯
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:
rem 使用通配符輸出當前目錄下所有後綴爲.txt的文件名
for %%i in (*.txt) do echo %%i
rem 使用通配符輸出當前目錄下所有後綴爲.txt文件名只有2個字符的文件名
for %%i in (??.txt) do echo %%i
3. 擴展用法
3.1 for /d用法
FOR /D %variable IN (set) DO command [command-parameters]
- /d指示set中的元素爲目錄。如果set中包含通配符,則指定與目錄名匹配,而不與文件名匹配。
- 示例
rem 循環輸出當前目錄下所有的目錄名
for /d %%i in (*) do echo %%i
rem 循環輸出當前目錄下,目錄名最後字符爲a的所有目錄名
for /d %%i in (*a) do echo %%i
3.2 for /r用法
FOR /R [[drive:]path] %variable IN (set) DO command [command-parameters]
- 檢查以 [drive:]path 爲根的目錄樹,指向每個目錄中的 FOR 語句。如果在 /R 後沒有指定目錄規範,則使用當前目錄。如果集僅爲一個單點(.)字符,則枚舉該目錄樹。
- 示例
rem 遍歷當前目錄下所有目錄,"/\."三者效果相同
for /r %%i in (.) do @echo %%i
for /r %%i in (\) do @echo %%i
for /r %%i in (/) do @echo %%i
rem 遍歷指定目錄
for /r e:\ %%i in (.) do @echo %%i
rem 遍歷當前目錄下所有文件並顯示完全路徑(包括子目錄)
for /r e:\ %%i in (*) do @echo %%i
for /r e:\ %%i in (*.txt) do @echo %%i
3.3. for /l用法
FOR /L %variable IN (start,step,end) DO command [command-parameters]
- 該集表示以增量形式從開始到結束的一個數字序列。因此,(1,1,5)將產生序列1 2 3 4 5,(5,-1,1)將產生序列(5 4 3 2 1)。
- 示例
rem 從1開始,以2爲步進值,循環到不超過10(包括等於)
for /l %%i in (1, 2, 10) do @echo %%i
rem 從10開始,以-2爲步進值,循環到不小於0(包括等於)
for /l %%i in (10, -2, 0) do @echo %%i
3.4. for /f用法
3.4.1. 語法介紹
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]
3.4.2. 參數介紹
- file-set, fileset 爲一個或多個文件名。繼續到 fileset 中的下一個文件之前,每份文件都被打開、讀取並經過處理。處理包括讀取文件,將其分成一行行的文字,然後將每行解析成零或更多的符號。然後用已找到的符號字符串變量值調用 For 循環。 以默認方式,/F 通過每個文件的每一行中分開的第一個空白符號。跳過空白行。
- options,可通過指定可選 “options” 參數替代默認解析操作。這個帶引號的字符串包括一個
或多個指定不同解析選項的關鍵字。這些關鍵字爲:- eol=c - 指一個行忽略的開始字符(就一個)
- skip=n - 指在文件開始時忽略的行數。
- delims=xxx - 指分隔符集。這個替換了空格和跳格鍵的默認分隔符集。
- tokens=x,y,m-n - 指每行的哪一個符號被傳遞到每個迭代 的 for 本身。這會導致額外變量名稱的分配。m-n格式爲一個範圍。通過 nth 符號指定 mth。如果符號字符串中的最後一個字符星號,那麼額外的變量將在最後一個符號解析之後分配並接受行的保留文本。
- usebackq - 指定新語法已在下類情況中使用:在作爲命令執行一個後引號的字符串並且一個單引號字符爲文字字符串命令並允許在 file-set中使用雙引號擴起文件名稱。
3.4.3 示例
rem 讀取當前目錄的a.txt,並顯示每一行的內容(每一行內容遇到空格即終止)
for /f %i in (a.bat) do @echo %i
rem 讀取多個文件,並顯示每一行的內容(每一行內容遇到空格即終止)
for /f %i in (a.bat b.txt) do @echo %i
rem 忽略以"s”開頭的行
for /f "eol=s“ %i in (a.bat) do @echo %i
rem 跳過前5行
for /f "skip=5" %i in (a.bat) do @echo %i
rem 集中的分隔符默認爲空格和tab鍵
rem 通過delims=顯式指定分隔符
for /f "delims=," %i in (a.bat) do @echo %i
rem 通過delims=顯式指定分隔符,可以指定多個
for /f "delims=,;" %i in (a.bat) do @echo %i
rem 提取分隔字符串指定部分
for /f "delims=, tokens=1" %%i in (test.txt) do echo %%i
rem 可以提取多個,從最前面指定的%%i順序往後取
for /f "delims=, tokens=1,2,3,4,5" %%i in (test.txt) do echo %%i %%j %%k %%l %%m
rem 上面的代碼可以簡化如下
for /f "delims=, tokens=1-5" %%i in (test.txt) do echo %%i %%j %%k %%l %%m
for /f "delims=, tokens=1-3,4,5" %%i in (test.txt) do echo %%i %%j %%k %%l %%m
rem *表示4之後的全部不分隔
for /f "delims=, tokens=1,2,3,4,*" %%i in (test.txt) do echo %%i %%j %%k %%l %%m
rem 集中的路徑被當作字符串處理
for /f %%a in (“C:\Documents and Settings\Administrator\桌面\note.txt”) do echo %%a
rem usebackq指示集中的是文件路徑
for /f "usebackq" %%a in (“C:\Documents and Settings\\note.txt”) do echo %%a
rem usebackq後面集中的單引號指定是字符串
for /f "usebackq" %%a in ('C:\Documents and Settings\\note.txt') do echo %%a
rem 集中的命令以``尖引號
for /f "usebackq" %i in (`dir /s /b`) do @echo %i
rem 效果和上面相同,集中命令以單引號‘’
for /f %i in ('dir /s /b') do @echo %i
rem 組合提取指定文件中的內容
for /f "eol=; tokens=1,2* delims=,- " %%i in (d:\test.txt) do echo %%i %%j %%k
4. 變量延遲
for語句隻影響後面的一句代碼,如果想寫多句代碼,必須用()。批處理解釋代碼時,是先讀出當前行的代碼並解析,for及之後的代碼也是一次加載並解釋的。這就導致for之後的代碼中的變量設置了並沒有立即生效。如果想要立即生效,需要啓用變量延遲。
- setlocal enabledelayedexpansion
啓用延遲的環境變量擴展,直到出現匹配的 endlocal 命令,無論 setlocal 命令之前的設置如何。 - setlocal disabledelayedexpansion
禁用延遲的環境變量擴展,直到出現匹配的 endlocal 命令,無論 setlocal 命令之前的設置如何。 - 示例,求0到100之和。
@echo off
setlocal enabledelayedexpansion
for /l %%i in (0, 1, 100) do (
set /a val+=%%i
@echo !val!
)
endlocal
pause