批處理命令 - for

0、功能

Runs a specified command for each file in a set of files.
對一組文件中的每一個文件執行某個特定命令。

 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

1、FOR命令簡介

for命令的基本用法如下,主要是處理文件\文件夾\命令結果.

複製代碼
FOR %variable IN (set) DO command [command-parameters]

  %variable          # Specifies a single letter replaceable parameter. ;指定一個單一字母可替換的參數,簡單的說就是vaiable取值範圍只能是a~z和A~Z中的一個字母。
FOR 變量是單一字母、分大小寫 是全局的變量,所以不能同時使用超過 52 個

  (set)              # Specifies a set of one or more files.  Wildcards may be used. ;指定一個或一組文件。可以使用通配符。
  command            # Specifies the command to carry out for each file. ;指定對每個文件執行的命令。
  command-parameters # Specifies parameters or switches for the specified command. ;爲特定命令指定參數或命令行開關。

To use the FOR command in a batch program, specify %%variable instead of %variable.  Variable names are case sensitive, so %i is different from %I.
在批處理程序中使用 FOR 命令時,指定變量請使用 %%variable 而不要用 %variable。變量名稱是區分大小寫,所以 %i 不同於 %I.
例如 echo %%T echo 是 command, %%T 則是 echo 的
command-parameters
複製代碼

1.1、應用舉例1 - 刪除當前文件文件夾下的1.txt、2.txt、3.txt、4.txt

@echo off 
for %%i in (1,2,3,4) do del %%i.txt 
pause

 

 1.2、應用舉例2 - 刪除當前文件文件夾下所有txt文件

@echo off 
for %%i in (*.txt) do del %%i
pause

 

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

2、FOR命令的參數

FOR有4個參數 /d   /l   /r   /f   他們的大體用途如下

1 /d    # Directory ;操作目錄
2 /r    # Recursion ;遞歸目錄,操作所有目錄下的文件
3 /f    # File      ;操作文件和字符串
4 /l    # Iteration ;迭代器,產生有序序列

 

2.1、參數/D - 操作目錄

FOR /D %variable IN (set) DO command [command-parameters]
If set contains wildcards, then specifies to match against directory names instead of file names. 如果集中包含通配符,則指定與目錄名匹配,而不與文件名匹配,只能顯示當前目錄下的目錄名字

2.1.1 應用舉例1 - 打印C盤根目錄下的所有文件夾的名稱(只有根目錄的文件夾,沒有子文件夾)

@echo off
cd c:
for /d %%T in (*) Do echo %%T
pause

2.1.2 應用舉例2 - 打印C盤根目錄下以"P"開頭的文件夾

@echo off
cd c:
for /d %%T in (P*) Do echo %%T
pause

Note: P不區分大小寫

2.1.3 應用舉例3 - 打印C盤根目錄下,文件夾名稱是1~3個字符的文件夾

@echo off
cd c:
for /d %%T in (???) Do echo %%T
pause

Note: 漢字算2個字符

2.1.4 應用舉例4 - 打印C盤根目錄下,文件夾名稱是以P或W開頭的文件夾

@echo off
cd c:
for /d %%T in (P*, W*) Do echo %%T
pause

Note: P 和 W 不區分大小寫

2.1.5 應用舉例5 - 打印C盤根目錄下,文件夾名稱是以P或者文件夾名稱是1~3個字符的文件夾

@echo off
cd c:
for /d %%T in (P*, ???) Do echo %%T
pause

Note: 多種篩選條件隨你組合,只要用","逗號分隔開就行

 

2.2、參數/R - 操作目錄下的文件

複製代碼
FOR /R [[drive:]path] %variable IN (set) DO command [command-parameters]

Walks the directory tree rooted at [drive:]path, executing the FOR statement in each directory of the tree.  
If no directory specification is specified after /R then the current directory is assumed.
If set is just a single period (.) character then it will just enumerate the directory tree. 檢查以
[drive:]path 爲根的目錄樹,指向每個目錄中的 FOR 語句。 如果在 /R 後沒有指定目錄規範,則使用當前目錄。
如果集僅爲一個單點(.)字符,則枚舉該目錄樹,即只操作文件夾,不操作文件。
複製代碼

 

 2.2.1、應用舉例1 - 打印出C盤目錄下所有的exe文件名

@echo off 
for /r c:\ %%T in (*.exe) do echo %%T
pause

因爲/R 參數的作用是遞歸目錄,所以無論多深路徑下的exe都會被找到

2.2.2、應用舉例2 - 打印出當前目錄(腳本所在目錄)下所有的exe文件名

@echo off 
for /r %%T in (*.exe) do echo %%T
pause

2.2.3、應用舉例3 - 打印出C盤根目錄下所有的文件夾及其子文件夾的名字(總之是個文件夾就打印其名字,不管他的路徑有多深)

@echo off
for /r c:\ %%T in (.) Do echo %%T pause

 這個是特例,只枚舉目錄樹,而不枚舉文件名

2.3、參數/L - 生成序列

複製代碼
FOR /L %variable IN (start,step,end) DO command [command-parameters]

The set is a sequence of numbers from start to end
, by step amount. So (1,1,5) would generate the sequence 1 2 3 4 5 and (5,-1,1) would generate the sequence (5 4 3 2 1) 該集表示以增量形式從開始到結束的一個數字序列。
因此,(
1,1,5)將產生序列1 2 3 4 5,(5,-1,1)將產生序列(5 4 3 2 1)
總結來說,就是等差數列.
複製代碼

 

2.3.1、應用舉例1 - 打印出1 ~ 5

@echo off 
for /l %%i in (1,1,5) do echo %%i 
pause

Note : 只能按行打印, 不能將1~5輸出到1行中

2.3.2、應用舉例2 - 打開5個計算器程序

@echo off 
for /l %%i in (1,1,5) do start calc 
pause

 

2.4、參數/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]

or, if usebackq option present:

如果使用了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]


file-set is one or more file names.  Each file is opened, read and processed before going on to the next file in file-set.
Processing consists of reading in the file, breaking it up into individual lines of text and then parsing each line into zero or more tokens.  
The body of the for loop is then called with the variable value(s) set to the found token string(s).
By default
, /F passes the first blank separated token from each line of each file. Blank lines are skipped. You can override the default parsing behavior by specifying the optional "options" parameter.
This is a quoted string which contains one or more keywords to specify different parsing options. The keywords are: file-set 爲一個或多個文件名。繼續到 file-set 中的下一個文件之前,每份文件都被打開、讀取並經過處理。處理包括讀取文件,將其分成一行行的文字, 然後將每行解析成零或更多的符號。然後用已找到的符號字符串變量值調用 For 循環。 默認方式,/F 通過每個文件的每一行中分開的第一個空白符號。跳過空白行。您可通過指定可選
"options" 參數替代默認解析操作。
這個帶引號的字符串包括一個或多個指定不同解析選項的關鍵字。這些關鍵字爲:
eol
=c # specifies an end of line comment character(just one) ;指一個行註釋字符的結尾(就一個)
skip
=n # specifies the number of lines to skip at the beginning of the file.指在文件開始時忽略的行數。
delims
=xxx # specifies a delimiter set. This replaces the default delimiter set of space and tab. 指定分隔符集。這個替換了空格和跳格鍵的默認分隔符集。
tokens
=x,y,m-n # specifies which tokens from each line are to be passed to the for body for each iteration. This will cause additional variable names to be allocated. The m-n form is a range,specifying the mth through the nth tokens. If the last character in the tokens= string is an asterisk,
then an additional variable is allocated and receives the remaining text on the line after the last token parsed.
指每行的哪一個符號被傳遞到每個迭代的 for 本身。這會導致額外變量名稱的分配。m-n格式爲一個範圍。通過 nth 符號指定 mth。
如果符號字符串中的最後一個字符星號,那麼額外的變量將在最後一個符號解析之後分配並接受行的保留文本

usebackq # specifies that the new semantics are in force,where a back quoted string is executed as a command and
a single quoted string is a literal string command and allows the use of double quotes to quote file names in filenameset.
指定新語法已在下類情況中使用:在作爲命令執行一個後引號的字符串並且一個單引號字符爲文字字符串命令並允許在 file-set中使用雙引號擴起文件名稱
微軟給出的解釋似乎狗屁不通,這個選項的具體用法見下面的例子.
複製代碼

 處理文件時, 將文件的每一行作爲一個元素, for 循環 每次處理的就是 一行文本. for命令會跳過空白行.

 

 2.4.1、不使用usebackq 選項

複製代碼
#不使用 usebackq 選項
FOR /F ["options"] %variable IN (file-set) DO command [command-parameters] # 處理文件, 文件在file-set文件集合中,注意,文件名和路徑中都不可以有空格,不能用雙引號括起來,否則需要使用usebackq選項 FOR /F ["options"] %variable IN ("string") DO command [command-parameters] # 處理字符串, 要處理的字符串就是雙引號括起來的內容 FOR /F ["options"] %variable IN ('command') DO command [command-parameters] # 處理命令的結果, 在DO 後面的command執行之前先執行括號中用單引號括起來的命令,該命名的輸出結果作爲for的輸入
複製代碼

 

2.4.1.1、處理文件

 FOR /F 命令主要是 處理一些有固定格式的文件

2.4.1.1.1、應用舉例1 - 顯示文件內容

假設C盤根目錄下有一個文件名字叫"myfile1.txt", 其中文件內容如下

The_First_Line
The_Second_Line
The_Thrid_Line
The_Fourth_Line

想要顯示完整的文件內容可以使用 type myfile1.txt 命令, 但是for命令也可以實現,可以使用下面的批處理腳本程序

@echo off 
for /f %%T in (C:\myfile1.txt) do echo %%T
pause

使用上面的腳本顯示文本內容與type命令相比會有如下限制

①會忽略空行, 空行不會輸出

②一行文本中不能有空格或者跳格鍵(TAB),否則只能輸出空格或者跳格鍵之前的文本

下面來看一個具體的例子

 假設C盤根目錄下有一個文件名字叫"myfile2.txt", 其中文件內容如下

第1行第1列 第1行第2列 第1行第3列 
第2行第1列 第2行第2列 第2行第3列
第3行第1列 第3行第2列 第3行第3列

 使用上面的腳本後,輸出結果如下: (空行被忽略了, 每行只打印空格之前的字符)

第1行第1列
第2行第1列
第3行第1列

 ★爲什麼會忽略空行呢?

→for /f 命令的默認屬性, 不可更改, 就是規定

★爲什麼會每行只打印空格或者跳格鍵之前的字符?

→這是因爲"delims" 選項的默認值是空格 和 跳格鍵

  所以上面的腳本等價於下面的腳本(注意等號後面是一個空格+一個TAB)

@echo off 
for /f "delims=     " %%T in (C:\myfile2.txt) do echo %%T
pause

 

假設C盤根目錄下有一個文件名字叫"myfile3.txt", 其中文件內容如下

第1行第1列,第1行第2列,第1行第3列
第2行第1列,第2行第2列,第2行第3列
第3行第1列,第3行第2列,第3行第3列

 如果只想要篩選出第1列的文本, 使用下面的腳本可以完成

@echo off 
for /f "delims=," %%T in (C:\myfile3.txt) do echo %%T
pause

delims 選項用來指定分隔符,使用該選項後,默認的分隔符(空格和TAB)就無效了,

分隔符可以有多種,依次在delims=後面羅列出來即可,多個分隔符之間不可以有其他符號,是緊密的連在一起的.

 

如果只想要篩選出第2列的文本, 使用下面的腳本可以完成

@echo off 
for /f "tokens=2 delims=," %%T in (myfile3.txt) do echo %%T
pause

 如果想要同時篩選出第2列和第3列, 使用下面的腳本可以完成

@echo off 
for /f "tokens=2,3 delims=," %%i in (myfile3.txt) do @echo %%i %%j
pause

 for /f 命令讀取文件時, 每一行作爲一個元素, 然後該元素使用 delims 指定的分隔符進行分割, 使其由一行本文變成幾個文本串, 文本串的索引從 1 開始。

例如 "第1行第1列,第1行第2列,第1行第3列" 這一行文本, 他被逗號分割成 3 個文本串,

第1個文本串:第1行第1列

第2個文本串:第1行第2列

第3個文本串:第1行第3列

tokens 選項的作用就是指定文本串的索引, 該選項的默認值爲1。

tokens 選項可以指定多個索引,多個索引之間使用逗號分隔。

多個索引如果是連續的,比如tokens=1,2,3則可以簡化成tokens=1-3,

部分連續也可以簡化,比如tokens=2,5,6,7,9可以簡化成tokens=2,5-7,9。

指定多個索引會導致額外變量名稱的分配,tokens指定了多少個索引,就要分配多少個變量,

注意 tokens=1-3 是需要分配3個變量的,不能看做一個集合只分配一個變量。

另外額外的變量是按照英文字母的順序分配的,如上例中 %%i 中被賦值第2個文本串, %%j被賦值第3個文本串。

按照字母順序,i 後爲 j,如果你將 %%j 改成 %%k 等非j的變量,都不會得到正確的輸出。

 

 如果想要顯示所有被逗號分隔的文本, 使用下面的腳本可以完成

@echo off 
for /f "tokens=1,2,3 delims=," %%i in (myfile3.txt) do @echo %%i %%j %%k
pause

 或者

@echo off 
for /f "tokens=* delims=," %%i in (myfile3.txt) do @echo %%i
pause

 Note : 這裏有一點注意,使用tokens=* 選項時,分隔符號也會被顯示出來,這一點與 tokens=1,2,3 是不同的,tokens=1,2,3指定的文本串是以空格爲間隔的。

tokens=* 表示該行所有的文本都賦值給%%i。

在tokens=*中, *也是需要分配變量的,再看一個例子tokens=2,3*,

同樣*也是需要分配變量的,這個配置選項是這樣工作的:

讀取文件的一行,使用分隔符分隔出第一個文本串,不是需要的,繼續分割出第二個文本串,是需要的,將其分配給%%i,

繼續分割出第三個文本串,是需要的,將其分配給%%j,*代表該行剩餘的文本,不用分隔,全都賦值給%%k,這也是使用*時會有分隔符的原因。

 

假設C盤根目錄下有一個文件名字叫"myfile4.txt", 其中文件內容如下(在一些格式化的文件中有大量的數據,所以需要有一定的註釋)

#這是第1個註釋
第1行第1列,第1行第2列,第1行第3列
#這是第2個註釋
第2行第1列,第2行第2列,第2行第3列
#這是第3個註釋
第3行第1列,第3行第2列,第3行第3列

 我們分析這個文件時,肯定是需要過濾掉註釋,只分析有用的數據

@echo off 
for /f "eol=# tokens=* delims=," %%i in (myfile4.txt) do @echo %%i
pause

 選項eol表示忽略以某個字符開頭的行,必須是單字符,並且該字符前不能有空格和TAB

 

假設C盤根目錄下有一個文件名字叫"myfile5.txt", 其中文件內容如下(第1~2行是無用的)

複製代碼
NoUseLine1
NoUseLine2
#這是第1個註釋
第1行第1列,第1行第2列,第1行第3列
#這是第2個註釋
第2行第1列,第2行第2列,第2行第3列
#這是第3個註釋
第3行第1列,第3行第2列,第3行第3列
複製代碼

 處理這個文件時想要略過第1~2行

@echo off 
for /f "eol=# skip=2 tokens=* delims=," %%i in (myfile5.txt) do @echo %%i
pause

 選項 skip 指定在文件開始時忽略的行數。

 2.4.1.2、處理字符串

 處理字符串 其實相當於處理文件的一行,實際中直接應用較少, 一般應用於處理一個腳本中上面程序得出的結果。

@echo off 
for /f "tokens=2,3 delims=," %%i in ("第1行第1列,第1行第2列,第1行第3列") do @echo %%i %%j
pause

 

2.4.1.3、處理命令結果

在命令行中輸入set命令後回車,得到的是所有環境變量的值,例如 windir=C:\Windows,

如果我們想要顯示所有的環境變量的名稱可以使用下面的腳本

@echo off 
for /f "tokens=1 delims==" %%i in ('set') do @echo %%i
pause

 

 

2.4.2、使用usebackq 選項

複製代碼
#使用 usebackq 選項,該選項在"options"中
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]  # 處理命令的結果, 在DO 後面的command執行之前先執行括號中用後引號括起來的命令,該命名的輸出結果作爲for的輸入 
複製代碼

 

2.4.2.1、處理文件

除了文件名(包含路徑)中允許有空格,必須使用雙引號括起來之外,與不使用usebackq沒有區別

@echo off 
for /f "usebackq" %%T in (“C:\Program Files\my file1.txt") do echo %%T
pause

 

2.4.2.2、處理字符串

與不使用usebackq選項的區別只是字符串使用單引號括起來,不使用雙引號

@echo off 
for /f "tokens=2,3 delims=, usebackq" %%i in ('第1行第1列,第1行第2列,第1行第3列') do @echo %%i %%j
pause

 

2.4.2.3、處理命令結果

與不使用usebackq選項的區別只是命令使用後引號括起來,不適用雙引號

@echo off 
for /f "tokens=1 delims== usebackq" %%i in (`set`) do @echo %%i
pause

 

2.4.3、使用 usebackq 選項與不使用 usebackq  選項的區別

 

處理內容 使用usebackq 不使用usebackq 備註
處理文件 文件名(含路徑)必須使用雙引號括起來 文件名(含路徑)不能使用雙引號括起來,文件名和路徑中不能有空格 區別就是你使用的文件名中是否有空格,如果作爲共通的處理,肯定要使用usebackq選項
處理字符串 字符串使用單引號括起來 字符串使用雙引號括起來 引用符號不同
處理命令結果 命令使用後引號括起來 命令使用單引號括起來 引用符號不同

 

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

3、FOR命令的進階

稍微複雜一點的應用。

3.1、執行多條命令

看了上面的例子,你可能會發現, 每次for循環只能執行一條命令,這在實際應用中遠遠不夠, 有什麼方法像C語言中的for那樣可以執行{}中的所有內容呢?

當然有那就是(), 需要注意的是 do 後要有空格然後跟着是"(" , 並且"(" 不可以另起一行。

@echo off 
for /f "tokens=1 delims== usebackq" %%i in (`set`) do (
echo ------------------------------------------------
echo %%i
)
pause

3.2、變量的增強 

In addition, substitution of FOR variable references has been enhanced.
You can now use the following optional syntax:
FOR 變量參照的替換已被增強。您現在可以使用下列選項語法:
複製代碼
    %~I         # expands %I removing any surrounding quotes (") ;刪除任何引號(")
    %~fI        # expands %I to a fully qualified path name ;將 %I 擴展到一個完全合格的路徑名
    %~dI        # expands %I to a drive letter only ;僅將 %I 擴展到一個驅動器號
    %~pI        # expands %I to a path only ;僅將 %I 擴展到一個路徑
    %~nI        # expands %I to a file name only ;僅將 %I 擴展到一個文件名
    %~xI        # expands %I to a file extension only ;僅將 %I 擴展爲文件後綴名
    %~sI        # expanded path contains short names only ;將 %I 擴展到文件的文件屬性
    %~aI        # expands %I to file attributes of file ;將 %I 擴展到文件的日期/時間
    %~tI        # expands %I to date/time of file ;將 %I 擴展到文件的大小
    %~zI        # expands %I to size of file ;將 %I 擴展到文件的大小
    %~$PATH:I   # searches the directories listed in the PATH environment variable 
                  and expands %I to the fully qualified name of the first one found.
                  If the environment variable name is not defined or the file is not found by the search, 
                  then this modifier expands to the empty string
                  ;查找 PATH 環境變量中的目錄,並將 %I 擴展到找到的第一個完全合格的名稱。
                  如果環境變量名未被定義,或者沒有找到文件,此組合鍵會擴展到空字符串

The modifiers can be combined to get compound results:
可以組合修飾符來得到多重結果:

    %~dpI       # expands %I to a drive letter and path only ;僅將 %I 擴展到一個驅動器號和路徑
    %~nxI       # expands %I to a file name and extension only ;僅將 %I 擴展到一個文件名和擴展名
    %~fsI       # expands %I to a full path name with short names only ;僅將 %I 擴展到一個帶有短名的完整路徑名
    %~dp$PATH:I # searches the directories listed in the PATH environment variable for %I and expands to the drive letter and path of the first one found.
                  ;搜索列在路徑環境變量的目錄,並將 %I 擴展到找到的第一個驅動器號和路徑。
    %~ftzaI     # expands %I to a DIR like output line ;將 %I 擴展到類似輸出線路的 DIR

In the above examples %I and PATH can be replaced by other valid
values.  The %~ syntax is terminated by a valid FOR variable name.
Picking upper case variable names like %I makes it more readable and
avoids confusion with the modifiers, which are not case sensitive.
在以上例子中,%I 和 PATH 可用其他有效值代替。
%~ 遇到一個有效的 FOR 變量名終止。選取類似 %I 的大寫變量名比較易讀,而且避免與不分大小寫的組合鍵混淆。
複製代碼

 C盤根目錄下有以一個文件名字爲"myfile.txt", 其內容如下:

"First", "Second","Thrid"

 

C:\Batch 文件夾下有名字爲"test.bat"的腳本,其內容如下:

複製代碼
@echo offfor /f  "delims=, usebackq" %%T in ("C:\Program Files\my file.txt") do (
    echo ---Original
    echo %%T
    echo ----expands %I removing any surrounding quotes
    echo %%~T
    echo ----expands %I to a fully qualified path name
    echo %%~fT
    echo ----expands %I to a drive letter only
    echo %%~dT
    echo ----expands %I to a path only
    echo %%~pT
    echo ----expands %I to a file name only
    echo %%~nT
    echo ----expanded path contains short names only
    echo %%~sT
    
    echo ----expands %I to a drive letter and path only
    echo %%~dpT
    echo ----expands %I to a full path name with short names only
    echo %%~fsT
    echo ----expands %I to a file name and extension only
    echo %%~nxT
    echo ----expands %I to a DIR like output line
    echo %%~ftzaT
)
pause
複製代碼

 其運行結果如下:

複製代碼

---Original
"First"
----expands I removing any surrounding quotes
First
----expands I to a fully qualified path name
c:\Batch\First
----expands I to a drive letter only
c:
----expands I to a path only
\Batch\
----expands I to a file name only
First
----expanded path contains short names only
c:\Batch\First
----expands I to a drive letter and path only
c:\Batch\
----expands I to a full path name with short names only
c:\Batch\First
----expands I to a file name and extension only
First

 
複製代碼

 注意: 擴展的路徑是與腳本的路徑有關的, 與腳本讀取的文件路徑無關,

另外,如果腳本所在的路徑名有空格,其中幾個命令的輸出是有問題的,使用時,需要驗證好.

沒有在test.bat中列出的命令的輸出是空的,具體的使用情況,我也沒有細究,就到這裏了...

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