| 我的GitHub | 我的博客 | 我的微信 | 我的郵箱 |
|---|---|---|---|
| baiqiantao | baiqiantao | bqt20094 | baiqiantao@sina.com |
目錄
FOR 命令使用總結
for /? > for_help.txt
- 在
批處理程序中使用 FOR 命令時,指定變量請使用%%variable而不要用%variable。 - 變量名稱是
區分大小寫的,所以%i不同於%I。
FOR
FOR %variable IN (set) DO command [command-parameters]
對一個 set 中的每一個元素(文件)執行某個特定命令。
%variable指定一個單一字母可替換的參數,可以使用但盡量不要使用數字(set)指定一個集合,每個元素(文件)之間,可以用空格、跳格、逗號、分號或等號分隔;可以使用通配符匹配文件command指定對每個元素(文件)執行的命令command-parameters為特定命令指定參數或命令行開關
for %%i in (1 2 3 4 5) do @echo %%i
for %%i in (c d e f g h i j k l m n o p q r s t u v w x y z) do if exist %%i: echo 存在分區%%i:
set /a num=0
for %%j in (%*) do set /a num+=1
echo 批處理文件調用的參數個數:%num%
for %%i in (*) do echo %%i %【當前目錄下的所有文件,不包括目錄】%
for %%i in (*.txt) do echo "%%i" %【當前目錄下的所有.txt文件】%
for %%i in (??.txt) do echo "%%i" %【當前目錄下的所有只用兩個字符作為文件名的.txt文件】%
列出當前目錄下各種文件的方法,最簡單的還是用
dir命令
FOR /D
FOR /D %variable IN (set) DO command [command-parameters]
D是指directory,即為了處理文件夾。
有通配符
- 當 set 中包含有通配符
?或*時,它會匹配文件夾,而不會匹配文件 - 不能匹配帶隱藏屬性的文件夾
- 它僅能匹配當前目錄下的
第一級文件夾,或是指定目錄位置上的一級文件夾,而不能匹配更深路徑下的子文件夾,即不能遞歸。
for /d %%i in (*) do echo %%i %【當前目錄下的所有子目錄,不包括文件】%
for %%i in (*) do echo %%i %【當前目錄下的所有文件,不包括目錄】%
無通配符
當 set 中不包含任何的通配符時,它的作用和上面不帶命令擴展時的語句無任何區別。
- 不會排除掉帶隱藏屬性的文件夾
- 不會排除掉文件
- 總之就是和不帶
/d時無任何區別
for /d %%i in (test test.txt) do echo %%i
for %%i in (test test.txt) do echo %%i
/D /R 同時使用
for /d /r其實是對/d參數的擴展,/d參數本身只能處理第一層文件夾,但是加上/r參數后就可以處理所有的子文件夾。
- 在 for 有限的 4 個參數中,只有
/d/r可以一起使用(不分前后順序) - 依然不能處理隱藏文件夾
For /d /r %%i in (*) do echo %%i
:: 顯示當前目錄下所有的文件夾(包括子文件夾),等價於【dir /ad /s /b】
FOR /R
FOR /R [[drive:]path] %variable IN (set) DO command [command-parameters]
R 是指Recursive,即遞歸,換一個通俗一點的叫遍歷文件夾。
- 列舉 set 及其之下的所有以
[drive:]path為根的子目錄,對這些文件夾都執行 command 語句 - 如果在
/R后沒有指定目錄,則默認使用當前目錄 - 由於
/R語句是邊列舉路徑邊進行處理,所以在處理大量路徑的時候,過程前期不會感到有停頓
set 是一個點號
如果 set 僅為一個點(.)字符,則枚舉該目錄樹
- 不能列舉帶隱藏屬性的目錄
- 列舉出來的路徑最后都帶有
斜杠和點號,例如D:\_test\.D:\_test\bqt\.
for /r D:\_test\bqt %%i in (.) do echo %%i
for /r \_test\bqt %%j in (.) do echo %%j
for /r %%k in (.) do echo %%k
set 帶通配符
列舉[[drive:]path]及其所有子目錄下滿足指定規則的文件(不包括文件夾)。
for /r d:\_test %%i in (*.txt *bat*) do echo %%i
:: 列舉指定目錄下所有.txt結尾的文件,或所有文件名中包括bat的文件,不包括文件夾
set 不帶點號或通配符
列舉[[drive:]path]及其所有的子目錄(不包括文件),都分別添加 set 的元素之后再顯示出來。
for /r D:\_test %%i in (包 青 天) do echo %%i
FOR /L
FOR /L %variable IN (start,step,end) DO command [command-parameters]
L是指loop,即循環的意思。該集表示以增量形式從開始到結束的一個數字序列
- 所有的for語句,都可以看成是一種循環,只是在
/l中,特指按照指定次數進行循環罷了 - start指起始值,step指步間距,end指終止值
- start、step和end都只能取整數,正負皆可
- 以上會遍歷出所有滿足以下條件的整數值:
k = start + n*step,並且k <= end,其中n=0,1,2,3...
必須保證能取到一個有效的數組序列
- 步間距step的值不能為0
- 當步間距step的值為正整數時,終止值end不能小於初始值start
- 當步間距step的值為負整數時,終止值end不能大於初始值start
for /L %%k in (0,1,3) do echo %%k %【0 1 2 3】%
for /L %%k in (0,-1,-3) do echo %%k %【0 -1 -2 -3】%
一般而言,for /l語句可以換成goto循環,但是,goto循環並不一定能被for /l語句替換掉。
- 當循環次數確定的時候,首選
for /l語句 - 當循環次數不確定的時候,只能使用
goto語句,因為這個時候需要用if之類的條件語句來判斷何時結束goto跳轉
FOR /F
FOR /F ["options"] %variable IN (file-set/"string"/'command') DO command [command-parameters]
基本用法
所有的對象,無論是文件、窗體、還是控件,在所有的非機器語言看來,無外乎都是的文本信息,可以說,編程的很大一部分工作,都是在想方設法絞盡腦汁如何提取這些文本信息。
而for /f就是被設計成專門用於解析文本的。
- 無論for語句做何種變化,它的執行過程仍然遵循基本的流程:依次處理每個元素,直到所有的元素都被處理為止
- 在
for /f語句中,這里的元素是指文件中的每一行,這是一條極為重要的規則
for /f %%i in (test.txt) do echo %%i %逐行打印指定文件的內容%
for /f %%i in (test.txt) do echo %%i&pause
delims
- 以指定的
符號列表(符號只能是一個字符/字母/數字/漢字)作為被處理的字符串的分隔符集,切分字符串 - 默認只提取
第一節的字符串作為最終結果 - 如果沒有指定
delims=符號列表這個開關,默認以空格鍵或跳格鍵作為分隔符號 - 可以一次性指定多個分隔符號
for /f "delims= " %%i in (test.txt) do echo %%i
for /f "delims=12青天ab" %%i in (test.txt) do echo %%i %這里面的分割符有6個%
tokens
tokens=后面一般跟的一個或多個是數字,每個數字之間用逗號分隔- 數字的含義是:提取由
delims=這一開關划分的第n節字符串,划分的節是從1開始算的 - 如果
tokens=后面指定了多個數字,那么形式變量必須按照字母順序定義,例如%%i%%j%%k - 如果要提取的內容是
連續的多節的話,那么連續的數字可以使用start-end的形式替換 - 如果
tokens=最后一個字符是星號,則后面的內容整體被星號所表示的一個變量接收
for /f "delims=, tokens=2" %%i in (test.txt) do echo %%i
for /f "delims=, tokens=1,3" %%i in (test.txt) do echo %%i---%%j
for /f "delims=, tokens=1,2-4" %%i in (test.txt) do echo %%i---%%j---%%k---%%l
for /f "delims=, tokens=1-2,4,5-8" %%i in (test.txt) do echo %%i
for /f "delims=, tokens=1,*" %%i in (test.txt) do echo %%i---%%j
for /f "delims=, tokens=1,2-3,*" %%i in (test.txt) do echo %%i---%%j---%%k---%%l
skip
skip=n,其中,n是一個正整數,表示在文件開始時要跳過的行數
for /f "skip=2" %%i in (test.txt) do echo %%i
eol
eol=表示忽略以指定字符打頭的行- 在指定字符的時候,
只能指定1個,也可以不指定(即強制指定字符為空) for /f語句是默認忽略以;打頭的行內容的(這種默認設置在delims=;時無效),很多時候,我們可以充分利用這個特點,比如,在設計即將用for讀取的配置文件的時候,可以在注釋文字的行首加上分號
for /f "eol=," %%i in (test.txt) do echo %%i
命令的 3 種形式
for /f %%i in (test.txt) do echo %%i %第2種形式:文件名%
for /f "delims=" %%i in ('dir .') do echo %%i %第2種形式:單引號+命令語句%
for /f "tokens=1,*" %%i in ("hello 包 青天 ") do echo %%i--%%j %第3種形式:雙引號+字符串%
usebackq 的使用
如果文件名中含有空格等特殊字符,例如test 1.txt,該怎么辦?
for /f %%i in (test 1.txt) do echo %%i %錯誤:找不到文件%
for /f %%i in ("test 1.txt") do echo %%i %錯誤:這是第3種形式,文件名被當做字符串處理了%
usebackq是一個增強型參數,當使用了這個參數之后,原來的for語句中第一個括號內的寫法要做如下變動:
- 如果第一個括號里的對象是
文件名的話,要用雙引號"括起來 - 如果第一個括號里的對象是一條
命令語句的話,原來的單引號'要改為后引號 - 如果第一個括號里的對象是
字符串的話,原來的雙引號"要改為單引號'
for /f "usebackq" %%i in ("test 1.txt") do echo %%i
FOR /F %%i IN ('set') DO @echo %%i %枚舉當前環境中的環境變量%
FOR /F "usebackq" %%i IN (`set`) DO @echo %%i
usebackq除了在處理帶空格的文件名時會用到外,根本就沒有其它的出場機會和存在價值。
遲環境變量的理解
變量延遲是批處理中一個十分重要的機制,它因預處理機制而生,用於復合語句,特別是大量使用於強大的for語句中,所以需要熟練地使用這一機制。
setlocal enabledelayedexpansion語句的解釋:
set設置,local本地(局部),enable能夠,delayed延遲,expansion擴展- 合起來就是:將變量設置為
局部變量,並延遲環境變量的擴展行為
批處理的執行過程是怎樣的?
自上而下,逐條執行逐條並不等同於逐行,這個條,是一條完整的語句的意思,並不是指一行代碼
什么樣的語句才算一條完整的語句?
- 在
非復合語句中,如果該語句占據了一行的位置,則該行代碼為一條完整的語句 - 在
復合語句中,整個復合語句是一條完整的語句,而無論這個復合語句占用了多少行的位置 - 常見的復合語句有:
for語句、if……else語句、用符號&、||、&&、|連接的語句,以及用括號括起來的語句塊
在代碼逐條執行的過程中,批處理解釋器會對每條語句做一些預處理工作,這就是批處理中大名鼎鼎的預處理機制!
預處理機制的基本過程:
- 首先,把
一條完整的語句讀入內存中,不管這條語句有多少行,它們都會被一起讀入 - 然后,識別出哪些部分是命令關鍵字,哪些是開關、哪些是參數,哪些是變量引用……
- 如果代碼語法有誤,則給出錯誤提示或退出批處理環境
- 如果順利通過,接下來,就把該條語句中所有被
引用的變量及變量兩邊的百分號對,用這條語句被讀入內存之前就已經賦予該變量的具體值來替換…… - 當所有的預處理工作完成之后,批處理才會執行每條完整語句內部每個命令的原有功能
所以,如果命令語句中含有
變量引用,並且某個變量的值在命令的執行過程中被改變了,即使該條語句內部的其他地方也用到了這個變量,也不會用最新的值去替換它們,因為某條語句在被預處理的時候,所有的變量引用都已經被替換成字符串常量了。
解決的辦法是:使用變量延遲擴展語句,即讓變量的擴展行為延遲一下,延遲之后,就可以讓復合語句內部的變量實時感知到變量值的變化,從而獲取我們想要的值
變量擴展是怎么一回事?
- 在許多可見的官方文檔中,均將使用一對百分號閉合環境變量以完成對其值的替換行為,稱之為
擴展(expansion) - 這其實是一個
第一方的概念,是從命令解釋器的角度進行稱謂的,而從我們使用者的角度來看,則可以將它看作是引用(Reference) - 說得直白一點,所謂的變量擴展,實際上就是很簡單的這么一件事情:
用具體的值去替換被引用的變量及緊貼在它左右的那對百分號
哪些場合需要使用變量延遲語句?
在復合語句內部,如果某個變量的值發生了改變,並且
改變后的值需要在復合語句內部的其他地方被用到,那么就需要使用變量延遲語句。
延遲變量的擴展行為的兩種方式:
- 在適當位置使用
setlocal enabledelayedexpansion語句,然后把原本使用百分號對閉合的變量引用改為使用感嘆號對來閉合;這種方式非常常見 - 在適當的位置使用
call語句,即:在原來命令的前部加上call命令,並把變量引用的單層百分號對改為雙層百分號對;這種方式用得較少
@echo off & setlocal enabledelayedexpansion
set num=0 && echo !num!
@echo off
set num=0 && call echo %%num%%
2019-12-25
