1. 程式人生 > >bat中for /f 如何截取任意行

bat中for /f 如何截取任意行

num add del key pre 忽略文件 ply 通配符 文件的

一、概述

for命令開關有很多,/L,/F,/R。這裏僅對含有/F的for進行分析,這個可能是最常用的,也是最強的命令,主要用來處理文件和一些命令的輸出結果。

1.命令格式:
(1).FOR /F ["options"] %%i IN (file) DO command
(2).FOR /F ["options"] %%i IN ("string") DO command--註意雙引號
(3).FOR /F ["options"] %%i IN (‘command‘) DO command--註意單引號

2.參數說明:

file代表一個或多個文件,可以使用通配符。
string 代表字符串
command代表命令
["options"]選項有多個:

eol=c - 指定一個行註釋字符,遇到c開頭的行就忽略掉。
skip=n - 指定在文件開始時忽略的行數。
delims=xxx - 指定分隔符。默認是空格和TAB。

tokens=x,y,m-n - 指每行的哪一個符號被傳遞到每個叠代
的 for 本身。這會導致額外變量名稱的分配。m-n
格式為一個範圍。通過 nth 符號指定 mth。如果
符號字符串中的最後一個字符星號,
那麽額外的變量將在最後一個符號解析之後
分配並接受行的保留文本。
usebackq - 1.把單引號字符串作為命令;2.允許中使用雙引號擴起文件名稱。

二、詳細介紹
1.FOR /F %%i IN (file) DO command
file為文件名,按照官方的說法是,for會依次將file中的文件打開,並且在進行到下一個文件之前將每個文件讀取到內存,按照每一行為一個元素,忽略空白的行。
假如文件d:\out.txt中有如下內容:

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

怎麽遍歷文件中的內容呢?下面的語句可以:
for /f %%i in (d:\out.txt) do echo %%i


執行過程:for會先打開out.txt,然後讀出out.txt裏面的所有內容,把它作為一個集合,並且以每一行(文件中無分隔符情況下)作為一個元素,用%%i依次代替每個元素,然後執行do後面的命令。


for /f會默認以每一行(無分隔符)來作為一個元素,但是有分隔符怎麽辦?假如out.txt內容變成如下:

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

那麽for /f %%i in (d:\out.txt) do echo %%i就無法將所有的內容顯示出來。顯示結果如下:

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

因為命令默認是以空格和TAB為分隔符,所以它遇到分割符之後,默認只取第一個,就將分割符後面的都丟掉了。

如果我們還想把每一行再分解更小的內容,該怎麽辦呢?for命令提供了更多的參數,它們就是:delims和tokens
delims :告訴for每一行應該拿什麽作為分隔符,默認的分隔符是空格和tab鍵
比如,我們執行下面的命令:

for /f "delims= " %%i in (d:\out.txt) do echo %%i

顯示的結果:

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

這個命令和for /f %%i in (d:\out.txt) do echo %%i的效果是一樣的。

如果我們想要每一行的後面的元素,那又如何呢?這個時候就可以利用tokens參數,它的作用就是當你通過delims將每一行分為更小的元素時,由tokens來控制要取哪一個或哪幾個。
還是上面的例子,執行如下命令:

for /f "tokens=2 delims= " %%i in (d:\out.txt) do echo %%i

執行結果:

第1行第2列
第2行第2列
第3行第2列
如果要顯示第二列和第三列,則換成tokens=2,3或tokens=2-3,全部顯示則使用通配符tokens=*。


註意:如果顯示多個元素(非*),比如這裏的tokens=2-3,語句應該寫成這樣:

for /f "tokens=2,3 delims= " %%i in (d:\out.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=2,* delims= " %%i in (d:\out.txt) do echo %%i %%j
它顯示從第二列到最後的一列,執行結果為:

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

用%%i代替第二列,用%%j代替剩余的所有。


最後還有skip,eol和usebackq。

skip就是要忽略文件的前多少行,eol用來指定當一行以什麽符號開始時,就忽略它。比如:

for /f "skip=2 tokens=*" %%i in (d:\out.txt) do echo %%i
結果為:

第3行第1列 第3行第2列 第3行第3列
用skip來告訴for跳過前兩行。

再如,當out.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 (d:\out.txt) do echo %%i

結果是:

第3行第1列 第3行第2列 第3行第3列
用eol來告訴for忽略以“.”開頭的行。

usebackq就是反轉的意思,他把字符串("out.txt")當做文件,或者把命令(‘command‘)當做字符串。

例如:

for /f "usebackq eol=# tokens=*" %%i in ("d:\out.txt") do echo %%i

結果是:

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

如果不加usebackq,則"d:\out.txt"會被當成字符串。

又例如:

for /f "usebackq tokens=*" %%i in (‘echo helloworld!‘) do echo %%i

結果:

echo helloworld,這裏命令被當成了字符串。

如果沒有usebackq

for /f "tokens=*" %%i in (‘echo helloworld!‘) do echo %%i

結果:

helloworld!

2.FOR /F ["options"] %%i IN ("string") DO command

例子:

for /f "tokens=2,* delims= " %%i in ("this is an example!") do echo %%i %%j

結果:

is an example!

對於字符串的處理類似於文件的處理,此處不再贅述。

3.FOR /F ["options"] %%i IN (‘command‘) DO command

該命令將command的執行結果作為集合,後面的處理類似文件處理,此處不再贅述。


方法1. 用find命令查找指定字符串

1 2 3 @Echo Off For /f "delims=" %%i in (‘Type 1.txt^|Find "疑似"‘) do (Echo %%i) Pause
追問:
如果我根本不知道1.txt內容,只知道共四行,想單獨顯示第二行,該怎麽寫?
追答:
1 2 3 4 5 6 @Echo Off&Setlocal Enabledelayedexpansion For /f "delims=" %%i in (1.txt) do ( Set /a n+=1 If !n!==2 Echo %%i ) Pause

只顯示第二行

追問:
本人較為愚鈍,沒看懂,但能實現,謝謝。若能寫個分別將1.txt中的2 4 6行內容分別賦給變量a b c 就再追加20分。謝謝
追答:
1 2 3 4 5 6 7 8 For /f "delims=" %%i in (1.txt) do ( Set /a n+=1 If !n!==2 Set a=%%i If !n!==4 Set b=%%i If !n!==6 Set c=%%i ) Echo %a% %b% %c% Pause

bat中for /f 如何截取任意行