天天看點

批處理指令--檔案篇之findstr

作者:批處理進階

#暑期創作大賽#

上篇我們學習了find這個指令,一起來回顧下:

find用途:

用來在某一個或多個檔案中查找指定的字元串并顯示包含指定字元串的行。

find參數格式:

FIND [/V] [/C] [/N] [/I] "string" [pathname(s)]

/V:顯示不包含指定字元串的所有行。

/C:隻顯示包含指定字元串的行數。

/N:在指定字元串行前顯示行号

/I:查找字元串不區分大小寫

這篇我們學習find的增強版findstr ,參數功能更多,連名字也名副其實:find string,在檔案中尋找字元串findstr。該指令也是一個外部指令,它的作用是使用正常表達式搜尋檔案中的文本模式,其用法用途類似于Linux下的grep指令,用于查找過濾指定字元串。EditPlus軟體也有類似的功能,如果不習慣批處理,EditPIus是個不錯的選擇。

首先還是來看一下文法。

批處理指令--檔案篇之findstr
批處理指令--檔案篇之findstr

看起來好像很複雜的樣子。不過不要擔心,主要是一些參數和元字元(正規表達式)的學習。在學習之前,我們了解下前面提到的正常表達式。

正常表達式,是用于指定文本類型的符号,與精确的字元串相反,标記使用文字字元和元字元。

每個在正常的表達式文法中,沒有特殊意義的字元,都是文字字元,與出現的該字元比對。例如字母和數字是文字元号。

元字元是在正常表達式文法中具有特殊意義(操作符或分隔符)的符号,使用在正規表達式中。

也就是findstr支援兩種模式,一種是字面上的文字模式,使用文字字元;一種是正規表達式,可接受一些有特殊意義的元字元符号。在兩種模式下輸出的結果及參數也不盡相同。

1.文字模式,也是普通的模式,需要加參數/l,使用文字搜尋字元串,find用的就是這種模式,find也隻有這種模式。

2.正則模式,findstr預設的模式,加不加/r其實findstr都表示開啟了正則模式。

為了友善叙述,我們還是把參數介紹和元字元先貼出來吧。

參數介紹:

findstr [/b] [/e] [/l] [/r] [/s] [/i] [/x] [/v] [/n] [/m] [/o] [/p] [/offline] [/g:file] [/f:file]

[/c:string] [/d:dirlist] [/a:ColorAttribute] [strings] [[Drive:][Path] FileName [...]]

/b (begin,開頭)

如果位于行的開頭則比對模式。

/e (end,結尾)

如果位于行的末尾則比對模式。

/l (literal,文字)

使用文字搜尋字元串。

/r (Regular Expressions,正規表達式)

使用搜尋串作為正常表達式。Findstr 将所有元字元解釋為正常表達式,除非使用了/l。

/s (subdirectory,子目錄)

在目前目錄和所有子目錄中搜尋比對的檔案

/i (ignore,忽略)

指定搜尋不區分(忽略)大小寫。

/x (exactly,精确地)

列印完全比對的行。

/v (excusive,排外,不NOT)

隻列印不包含比對的行。

/n (number,号碼)

在每個比對的行之前列印行号。

/m (match,filename,比對,檔案名)

如果檔案包含比對項,僅列印該檔案名。

/o (offset,偏移)

在每次比對行之前列印查找偏移量。

跳過包含非可列印字元的檔案。

/offline(offline,脫機)

利用脫機屬性設定處理檔案

/f:file (file,檔案)

從指定檔案中讀取檔案清單。

/c:string (consoles,控制台,specified指定的)

使用指定的文本作為文字搜尋字元串。

/g:file(get,grep,得到,搜尋)

從指定檔案得到搜尋字元串。

/d:dirlist(dirlist,目錄清單)

搜尋以逗号分隔的目錄清單。

/a:ColorAttribute

使用兩個十六進制數指定顔色屬性。

strings (字元串)

指定要在 FileName中搜尋的文本。

[Drive:][Path] FileName […]

指定要搜尋的檔案。

元字元介紹:

.通配符:任何字元

*重複:以前字元或類的零次或多次出現

^行位置:行的開始

$行位置:行的結尾

[class]字元類:集合中任何一個字元

[^class]反類:不在集合中的任何一個字元

[x-y]範圍:指定範圍内的任何字元

\x取消:元字元x的文字用途

\<xyz字位置:字首

xyz\>字位置:字尾

下面開始介紹

文法:

1.findstr 參數 字元串 檔案名(含路徑,相對或絕對),這個順序不能變,不同于find的可變順序。

2.findstr字元串沒有加引号,是的,你沒看錯,表示什麼呢,表示字元串可不加引号,也可用雙引号括起來,也不同于find的必須加引号。

3.findstr的多個參數可連寫,也可單寫,如/ic:,/bi等,不同于find必須一個個的寫出來(單寫),如/i /v。

4.findstr字元串支援正則和通配,可多個,find不支援,隻能是一個指定的字元串。

參數:

1.搜尋的不同

a、有參沒參大不同

findstr "hello there" x.y

在檔案x.y中查找"hello"或"there"并顯示出包含這些字元串的行

findstr /c:"hello there" x.y

在檔案x.y中查找"hello there"并顯示出包含這個字元串的行

注意:findstr的參數/c是指定字元串的意思,代表引号内的字元串比對(含空格);find的參數/c是指定字元串的行數(有多少行)。

b、參數不同搜尋迥異

假如cc.txt檔案裡有如下行

^happy

happy birthday

happy day

findstr /ln "^happy" cc.txt

顯示第一行

findstr /n "^happy" cc.txt

顯示第二、三行

findstr /rn "^happy" cc.txt

顯示第二、三行

::可以看出第一個指令使用了文字模式,元字元失效,第二三個均是正則,findstr預設開了正則模式,是以第二三個是等價的。

2.列印完全比對的行 /x

findstr /xn "day" cc.txt

顯示第三行

3.遞歸查找 /s

也就是在目錄及其子目錄中搜尋比對的檔案,如:

:: 搜尋目前目錄及子目錄下所有的 .txt 檔案,并查找還有 hello 字元串的行, 并顯示行号

findstr /n /s "hello" *.txt

4.反向比對 /v

findstr /v "hello" test.txt

5.忽略大小寫 /i

findstr /i "Day#34; cc.txt

6.比對僅列印檔案名 /m

findstr /mi "\<Windows\>" *.*

元字元:

1.代表任何字元的通配符為.不是*。

*是重複符,在正規表達式中的作用,是表示左側字元或者表達式的重複次數,*号表示重複的次數為零次或者多次。

.*代表任意字元串。

2.^的作用

a.代表行的位置:行的開始。如^a代表該行以a開始。

如果要搜尋以 FOR 開頭的行,可以使用以下指令:

findstr /b /r /c:^FOR *.txt

b.取反,反類,不在集合中的任何一個字元。如[^x-yX-Y]代表不是任何一個大小寫字母。

如果要搜尋包含數字 0 到 9 以外的任何字元的行,可以使用以下指令:

findstr /r /c:[^0-9] *.txt

在 findstr 中,^ 是一個元字元,表示行中的位置。如果 ^ 位于正規表達式的開頭,它表示比對行的開頭。如果 ^ 位于方括号内,它表示反向類,即比對不在方括号内的任何字元。

c.轉義,如findstr用在for /f的in後括号裡被單引号''包覆時,管道符号|前的^就代表轉義。for /f指令裡的特殊字元(如|)要轉義,如:

for /f "skip=1 tokens=1,3" %%i in ('query user ^| findstr /v /c:" Disc "') do (actions)

在批處理檔案中,^ 是一個轉義字元,用于表示緊跟其後的字元的字面意義,而不是特殊含義。

是以,這段代碼裡的^|表示一個普通的管道符号,而不是一個元字元。它用于将 query user 指令的輸出傳遞給 findstr 指令,進行文本過濾。

如果不使用 ^ 進行轉義,批處理檔案會将 | 解釋為一個指令分隔符,而不是一個管道符号。這樣就會導緻文法錯誤或意外的結果。

3.$:行位置:行的結尾,如前面提到的例子findstr /i "Day#34; cc.txt。

^和$符号的應用

^ 表示行首比對,"^hero"僅比對 "heroisme"中的第一個單詞。

$ 表示行尾比對,"hero#34;僅比對 "iamthehero"中最後一個單詞。

4.[]表示集合,字元集,[X-Y]表集合内的任何一個字元,X-Y表任何一個大寫字母,另外還有[0-9]等,表示範圍内的任意一個。如果前面有^存在,則取反,如[^class]就是[class]的反類。

5.字首與字尾,\<Windows與Windows\>

如前文的findstr /mi "\<Windows\>" *.*

findstr "\<echo" 123.txt

所有含有以echo為字首的字元串的行,都比對。

findstr "echo\>" 123.txt

所有含有以echo為字尾的字元串的行,都比對。

findstr "\<end\>123.txt

這裡是用來精确查找單詞。查找單詞end的行,因為\<xyz\>格式要查找的是單個英文單詞。

6.\X,取消:元字元X的文字用途,如\^表示^符号本身,不代表文字開頭。\.表示.而不是元字元含義的任何字元。

5和6裡,可以把\當作轉義符号。

特别地:

1."[.*]" 如果在字元集内插入通配符和重複符号将視為普通字元,沒有通配和重複的含義。

2.要查找的字元串含有\時,可以用\\把\給轉義(一個\用二個\\代替),如果目标字元串的\後面還有内容,則搜尋字元串\除了要變成\\(本身的轉義要求),還可以在它後面再加一個字元,如\\.

findstr "\.abc" 123.txt

在檔案123.txt中查找可以比對“.abc”字元串的行,這裡\.是把.給轉義了。

findstr "1\\" 123.txt

在檔案123.txt中查找可以比對“1\”字元串的行,這裡\\是把\給轉義了。

轉義符 \

把表達式中的特殊字元(元字元)轉化為普通字元。常見寫法:

\.

\*

\\

\[

\]??

\-

3.搜尋引号,一個雙引号用兩個雙引号來包,如搜尋"56"(含雙引号),可寫成"""56"""

批處理裡的應用:

主要是搭配for使用,結合type,管道符|,重定向>,>>等使用。

@echo off&echo 稍候...

for /r "MT" %%i in (*.txt) do (

for /f "tokens=1* delims=:" %%i in ('findstr/n .* %%~si')do (

echo %%i |findstr "152")

)

上面主要是在檔案裡的每一行前加行号,.*代表任意字元串,我們之前提到過的。do括号裡的findstr盡管前面有管道,但不需要再轉義,我們在find章提到過。

findstr/n .* %%~si

繼續閱讀