首頁 > 軟體

grep命令中文手冊(info grep翻譯)

2020-06-16 17:08:46

1.本文為info man的譯文,基本按照原文翻譯,有幾個用不上的選項沒有翻譯,但為了文章的完整性,給出了原文。
2.譯文中有些"(註:)",為本人自行加入,幫助理解和說明,非原文內容!


本文目錄:

1 簡介
2 呼叫grep程式

2.1 命令列選項

2.1.1 一般選項
2.1.2 控制匹配模式
2.1.3 控制輸出內容
2.1.4 控制輸出行的字首
2.1.5 控制輸出行的上下文
2.1.6 篩選檔案和目錄
2.1.7 其他選項

2.2 退出狀態碼
2.3 各種grep程式

3 正規表示式

3.1 基本結構
3.2 字元類和中括號表示式
3.3 反斜線字元和特殊的表示式
3.4 錨定
3.5 後向參照和子表示式
3.6 基礎正則和擴充套件正則的比較

4 使用範例
5 已知的一些Bug


 

1 Introduction


'grep'用於搜尋給定檔案中能匹配給定pattern列表的行。當某行能匹配上,(預設)將拷貝該行到標準輸出,或者根據你所指定的選項生成其它序列的輸出。

儘管'grep'所期望的是在文字行中做匹配,但即使某輸入行的大小長度超出了可用記憶體空間也不會受到限制,它仍可以匹配一行中任意字串。如果輸入檔案的最後一個位元組不是換行符,'grep'會自動補上一個。由於換行符也是pattern列表的分隔符,因此沒有任何辦法匹配文字中的換行符。

 

2 Invoking 'grep'


'grep'命令列的一般語法格式為:

grep OPTIONS PATTERN INPUT_FILE_NAMES

OPTIONS部分可以指定0或多個。只有當沒有使用"-e PATTERN"或"-f FILE"時,指定的PATTERN才被grep可視。可以指定0或多個INPUT_FILE_NAMES。

 

2.1 Command-line Options(命令列選項)

'grep'有大量選項可用:一些是POSIX.2中的,一些是GNU擴充套件的。長選項都是GNU擴充套件選項,即使它們來自於POSIX。由POSIX指定的短選項,被明確標註為便於POSIX可移植性程式設計。有少數幾個選項是為了相容古老版本的grep。 有幾個額外的選項用於控制使用哪種變體'grep'匹配引擎(註:fgrep/grep/egrep)。

 

2.1.1 Generic Program Information

'--help'
輸出簡短的grep命令列使用幫助並退出。

'-V'
'--version'
輸出'grep'的版本號。

 

2.1.2 Matching Control(控制匹配模式)

'-e PATTERN'
'--regexp=PATTERN'
明確指定使用此處的PATTERN作為待匹配的pattern。該選項可以指定多次,它可以保護以"-"開頭的pattern。('-e'是POSIX指定的選項。)

'-f FILE'
'--file=FILE'
從FILE中獲取pattern列表,每行一個pattern。空的FILE表示不給定任何pattern,所以不會匹配到任何內容。('-f'是POSIX指定的選項。)

'-i'
'-y'
'--ignore-case'
忽略PATTERN中的大小寫,也忽略輸入檔案中的大小寫區別。'-y'是廢棄的用於和老版本保持相容性的選項。('-i'是POSIX指定的選項。)

'-v'
'--invert-match'
反轉匹配的結果,即選擇那些未匹配到的行。('-v'是POSIX指定的選項。)

'-w'
'--word-regexp'
僅選擇能精確匹配整個單詞的行。單詞的組成字元包括:字母、數位和下劃線。除了這些字元,其餘都是該選項篩選單詞時的單詞邊界分隔符。 (註:例如字串"fstab fstab(5)",grep -w 'fstab'或grep -w 'fsta.'能匹配這兩個單詞,但grep -w 'fsta'無法匹配任意一個)

'-x'
'--line-regexp'
僅選擇能精確匹配整行內容的行。('-x'是POSIX指定的選項。)
(註:例如某行"abcde",grep -x 'abc'將無法匹配該行,而grep -x 'abcd.'能匹配該行)

 

2.1.3 General Output Control(控制輸出內容)

'-c'
'--count'
不再輸出匹配的內容,而是輸出匹配到的行數量。如果給定了"-v"選項,則輸出未匹配到的行數量。('-c'是POSIX指定的選項。)

'--color[=WHEN]'
'--colour[=WHEN]'
對匹配到的內容賦予顏色並輸出。WHEN的有效值包括:'never'、'always'或'auto'。

'-L'
'--files-without-match'
不再輸出匹配的內容,而是輸出未能被匹配到的檔名,當某檔案中的某行被匹配到,將不再繼續向下搜尋該檔案。
(註:和"-l"輸出的檔名相反)

'-l'
'--files-with-matches'
不再輸出匹配的內容,而是輸出能被匹配到的檔名,當某檔案中的某行被匹配到,將不再繼續向下搜尋該檔案。('-l'是POSIX指定的選項。)

'-m NUM'
'--max-count=NUM'
當匹配成功的行有NUM行時,停止讀取檔案。如果是普通檔案作為標准輸入,則輸出這匹配到的NUM行。grep會在最後一次匹配行後做位置標記,使得呼叫的另一個進程可以從此處恢復並繼續向下搜尋。例如,下面的shell指令碼:

while grep -m 1 PATTERN
do
echo xxxx
done < FILE

而下面的shell指令碼則以不同於上面指令碼方式執行,因為此處使用的是管道,這不是一個實體檔案:

cat FILE |
while grep -m 1 PATTERN
do
echo xxxx
done

(註:如果對這兩個指令碼有疑問,可參考while迴圈中的陷阱,該文章中解釋了管道和檔案直接重定向時的區別)

'-o'
'--only-matching'
輸出被匹配到的字串,而不是輸出整行。每個被匹配到的字串都使用單獨的行輸出。

'-q'
'--quiet'
'--silent'
靜默模式,立即退出,即使遇到了錯誤。不寫任何內容到標準輸出。如果匹配到了內容則退出狀態碼為0。('-q'是POSIX指定的選項。)

'-s'
'--no-messages'
禁止輸出因檔案不存在或檔案沒有讀許可權而產生的錯誤資訊。('-s'是POSIX指定的選項。)

(註:由於POSIX和GNU grep的差異性,在可移植性的指令碼中,應儘量避免使用"-q"和"-s",而是使用重定向的方式重定向到/dev/null)

 

2.1.4 Output Line Prefix Control(控制輸出行的字首)

當輸出行有字首要輸出時,它們的順序總是:檔名、行號、位元組的偏移量,這個順序不會因為字首控制選項的順序而改變。

'-b'
'--byte-offset'
Print the 0-based byte offset within the input file before each line of output. If '-o' ('--only-matching') is specified, print the offset of the matching part itself. When 'grep' runs on MS-DOS or MS-Windows, the printed byte offsets depend on whether the '-u' ('--unix-byte-offsets') option is used; see below.

'-H'
'--with-filename'
輸出匹配到內容所在檔案的檔名。當指定了多個輸入檔案時,這是預設的。

'-h'
'--no-filename'
禁止輸出檔名。當只有一個輸入檔案時,這是預設的。

'--label=LABEL'
Display input actually coming from standard input as input coming from file LABEL. This is especially useful when implementing tools like 'zgrep'; e.g.:

gzip -cd foo.gz | grep --label=foo -H something

'-n'
'--line-number'
輸出匹配內容在檔案中的行號,每個檔案都單獨從1開始計數。('-n'是POSIX指定的選項。)

'-T'
'--initial-tab'
Make sure that the first character of actual line content lies on a tab stop, so that the alignment of tabs looks normal. This is useful with options that prefix their output to the actual content:'-H', '-n', and '-b'. In order to improve the probability that lines from a single file will all start at the same column, this also causes the line number and byte offset (if present) to be printed in a minimum-size field width.

'-u'
'--unix-byte-offsets'
Report Unix-style byte offsets. This option causes 'grep' to report byte offsets as if the file were a Unix-style text file, i.e., the byte offsets ignore the 'CR' characters that were stripped. This will produce results identical to running 'grep' on a Unix machine. This option has no effect unless the '-b' option is also used; it has no effect on platforms other than MS-DOS and MS-Windows.

'-Z'
'--null'
在輸出檔名時,使用""放在檔名後,這會替換原本使用的字元,如換行符或冒號。例如"grep -lZ"輸出的每個檔案都在同一行而不是分行,"grep -HZ"使得檔名後沒有冒號。

 

2.1.5 Context Line Control(控制輸出行的上下文)

無論下面的選項如何設定,grep都不會多次輸出同一行。如果指定了"-o"選項,這些選項將失效,並給出一個警告。

'-A NUM'
'--after-context=NUM'
除了輸出匹配到的行,還輸出匹配到內容的後NUM行。

'-B NUM'
'--before-context=NUM'
除了輸出匹配到的行,還輸出匹配到內容的前NUM行。

'-C NUM'
'-NUM'
'--context=NUM'
除了輸出匹配到的行,還輸出匹配到內容的前NUM行和後NUM行。

'--group-separator=STRING'
當使用'-A', '-B' or '-C'時,使用STRING替代預設的組分隔符。

(註:組分隔符表示匹配到的內容的上下文。例如"-A 2",在某行匹配到時,還將輸出後兩行,這是一個組。下一次匹配成功時,如果是在該組之後行匹配上的,則這兩組中間預設使用"--"分隔)

'--no-group-separator'
當使用'-A', '-B' or '-C'時,不輸出任何組分隔符,而是將不同組相鄰輸出。

 

2.1.6 File and Directory Selection(檔案和目錄的選擇)

'-a'
'--text'
Process a binary file as if it were text; this is equivalent to the '--binary-files=text' option.

'--binary-files=TYPE'
If the first few bytes of a file indicate that the file contains binary data, assume that the file is of type TYPE. By default, TYPE is 'binary', and 'grep' normally outputs either a one-line message saying that a binary file matches, or no message if there is no match. If TYPE is 'without-match', 'grep' assumes that a binary file does not match; this is equivalent to the '-I' option. If TYPE is 'text', 'grep' processes a binary file as if it were text; this is equivalent to the '-a' option. Warning: '--binary-files=text' might output binary garbage, which can have nasty side effects if the output is a terminal and if the terminal driver interprets some of it as commands.

'-D ACTION'
'--devices=ACTION'
If an input file is a device, FIFO, or socket, use ACTION to process it. By default, ACTION is 'read', which means that devices are read just as if they were ordinary files. If ACTION is 'skip', devices, FIFOs, and sockets are silently skipped.

'-d ACTION'
'--directories=ACTION'
If an input file is a directory, use ACTION to process it. By default, ACTION is 'read', which means that directories are read just as if they were ordinary files (some operating systems and file systems disallow this, and will cause 'grep' to print error messages for every directory or silently skip them). If ACTION is 'skip', directories are silently skipped. If ACTION is 'recurse', 'grep' reads all files under each directory, recursively; this is equivalent to the '-r' option.

'--exclude=GLOB'
忽略basename能被GLOB匹配到的檔案。GLOB萬用字元包括:"*"、"?"和"[...]"。

'--exclude-from=FILE'
從FILE中讀取exclude的排除規則。

'--exclude-dir=DIR'
篩選出不進行遞回搜尋的目錄,使用DIR進行匹配。

'-I'
Process a binary file as if it did not contain matching data; this is equivalent to the '--binary-files=without-match' option.

'--include=GLOB'
只搜尋basename能被GLOB匹配的檔案。

'-r'
'-R'
'--recursive'
從命令列中給定的目錄中遞回進去,搜尋其中的每個檔案和目錄。

 

2.1.7 Other Options(其他選項)

'--line-buffered'
Use line buffering on output. This can cause a performance penalty.

'--mmap'
This option is ignored for backwards compatibility. It used to read input with the 'mmap' system call, instead of the default 'read' system call. On modern systems, '--mmap' rarely if ever yields better performance.

'-U'
'--binary'
Treat the file(s) as binary. By default, under MS-DOS and MS-Windows, 'grep' guesses the file type by looking at the contents of the first 32kB read from the file. If 'grep' decides the file is a text file, it strips the 'CR' characters from the original file contents (to make regular expressions with '^' and '$' work correctly). Specifying '-U' overrules this guesswork, causing all files to be read and passed to the matching mechanism verbatim; if the file is a text file with 'CR/LF' pairs at the end of each line, this will cause some regular expressions to fail. This option has no effect on platforms other than MS-DOS and MS-Windows.

'-z'
'--null-data'
以""作為輸入行的分隔符,而不再以換行符分隔兩行。
(註:這為grep提供了簡單的跨行匹配的能力。見後文範例14。)

 

2.2 Exit Status(退出狀態碼)

通常情況下,如果能匹配到內容,則退出狀態碼為0,否則為1。但是如果發生了錯誤,則退出狀態碼為2,除非使用了"-s"或"-q"選項。

 

2.3 'grep' Programs(各種grep程式)

有4種grep程式分別支援不同的搜尋引擎,使用下面4個選項可以選擇使用哪種grep程式。

'-G'
'--basic-regexp' 使用基礎正規表示式引擎解析PATTERN,因此只支援基礎正規表示式(BRE)。這是預設grep程式。

'-E'
'--extended-regexp'
使用擴充套件正規表示式引擎解析PATTERN,因此支援擴充套件正規表示式(ERE)。('-E'是POSIX指定的選項。)

'-F'
'--fixed-strings'
不識別正規表示式,而是使用字元的字面意義解析PATTERN,因此只支援固定字串的精確匹配。('-F'是POSIX指定的選項。)

'-P'
'--perl-regexp'
使用perl正規表示式引擎解析PATTERN,因此支援Perl正規表示式。但該程式正處於研究測試階段,因此會給出一個警告。

此外,"grep -E"和"grep -F"可分別簡寫為egrep和fgrep。但這兩個簡寫程式是傳統寫法,已被廢棄,雖仍支援,但只是為了相容老版本程式。
(註:還有zgrep和pgrep,但它們不是grep家族的程式,zgrep是gzip提供,pgrep用於檢視進程名和pid的對映關係)

 

3 Regular Expressions(正規表示式)


正規表示式是一種用於描述字串集合的表示式。正規表示式類似於算術表示式,也使用各種操作符組合各短小表示式。grep可以理解三種不同版本的正規表示式:基礎正規表示式BRE、擴充套件正規表示式ERE和Perl正規表示式。下面所描述的是擴充套件正規表示式的內容,在後文會比較BRE和ERE的不同之處。而Perl正則功能更完整、效能更好,可以從pcresyntax(3)和pcrepattern(3)中獲取詳細資訊,但有些作業系統中可能無法獲取。

 

3.1 Fundamental Structure(基本結構)

基本結構塊是匹配單個字元的正規表示式。大多數位符,包括字母和數位,都能自己匹配自己,例如給定正規表示式"a",它能匹配字母a。所有的元字元都具有特殊意義,需要使用反斜線進行跳脫。

正規表示式可以使用下面幾種方式來表示重複次數。

'.'
點"."可以匹配任意單個字元。

'?'
可以匹配前一個條目0或一次。例如,"ca?b"可以匹配"cb"也可以匹配到"cab",但不能匹配到"caab"。如果使用了分組,如"c(ca)?b"能匹配"cb"或"ccab"。

'*'
匹配前一個條目0或任意多次。

'+'
匹配前面的條目一次或多次。

'{N}'
匹配前面的條目正好N次。

'{N,}'
匹配前面的條目N次或更多次。即至少匹配N次。

'{,M}'
匹配前面的條目最多M次。即匹配0到M次。

'{N,M}'
匹配前面的條目N到M次。

兩個正規表示式可以進行串聯,串聯後的匹配結果是這兩個正規表示式的匹配結果進行的串聯。例如正規表示式"ab"就是"a"和"b"串聯後的正則。

兩個正規表示式還可以使用豎線符號"|"進行連線,這表示二者選一,只要能匹配豎線兩邊任意一個正在表示式均可,若能同時匹配上也可。例如字串"acx"、"bx"、"accb"均能被正規表示式"ac|b"匹配上,其中"accb"被同時匹配上。

重複次數的符號優先順序高於串聯高於二者選一符號"|",使用括號可以改變優先順序規則。

 

3.2 Character Classes and Bracket Expressions(字元類和中括號表示式)

中括號正規表示式是使用"["和"]"包圍的字元列表。它能匹配該列表中的任意單個字元。如果列表中的第一個字元是"^",則表示不匹配該列表中的任意單個字元。例如,'[0123456789]'能匹配任意數位。

中括號中可以使用連字元"-"連線兩個字元表示"範圍"。例如,C字元集下的"[a-d]"等價於"[abcd]"。大多數位符集規則和字典排序規則一樣,這意味著"[a-d]"不等價於"[abcd]",而是等價於"[aBbCcDd]"。可以設定環境變數"LC_ALL"的值為C使得採取C字元集的排序規則。

最後,預定義了幾個特定名稱的字元類,它們都使用中括號包圍。如下:

'[:alnum:]'
匹配大小寫字母和數位。等價於字元類'[:alpha:]'與字元類'[:digit:]'的和。

'[:alpha:]'
字母字元類。匹配大小寫字母。等價於字元類'[:lower:]'和字元類'[:upper:]'的和。

'[:blank:]'
空白字元類。包括:空格和製表符。

'[:cntrl:]'
控制字元類。在ASCII中,這些字元的八進位制程式碼從000到037,還包括177(DEL)。

'[:digit:]'
數位字元類。包括:'0 1 2 3 4 5 6 7 8 9'。

'[:graph:]'
繪圖類。包括:大小寫字母、數位和標點符號。等價於

'[:lower:]'
小寫字母類。包括:'a b c d e f g h i j k l m n o p q r s t u v w x y z'。

'[:print:]'
列印字元類。包括:大小寫字母、數位、標點符號和空格。等價於字元類'[:alnum:]'與字元類'[:punct:]'和空格的和。

'[:punct:]'
標點符號類。包括:'! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ ] ^ _ ' { | } ~'。

'[:space:]'
空格字元類。包括:空格、製表符、垂直製表符、換行符、回車符和分頁符。

'[:upper:]'
大寫字母類。包括:'A B C D E F G H I J K L M N O P Q R S T U V W X Y Z'。

'[:xdigit:]'
十六進位制類。包括:'0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f'。

例如,"[[:alnum:]]"表示"[0-9A-Za-z]","[^[:digit:]]"表示[^0123456789],"[ABC[:digit:]]"表示"[ABC0-9]"。注意,字元類必須包含在額外的中括號內。

中括號中的大多數元字元都丟失了它們特殊意義,而成為普通的字面符號。

']'
該符號表示中括號的結束。如果要匹配該字面字元,則必須將其放在字元列表的最前面。即"[]...]"。

'[.'
該符號表示排序符號的開始。
(註:排序類需要在字元集中預先定義好才能使用。例如[.ab.]表示將“ab”作為整體匹配,不匹配a或b。但預設情況下,字元集裡肯定是沒有定義好"ab"這個排序整體的,所以無法使用)

'.]'
表示排序符號的結束。

'[='
表示等價類的開始。
(註:例如,[=e=]表示將字母e的第一聲和第三聲等不同音節的同字母看成相同字元。)

'=]'
表示等價類的結束。

'[:'
表示字元類的開始。

':]'
表示字元類的結束。

'-'
該字元是範圍連線符,因此要匹配該符號的字面意義,需要將其放在列表的最前面或最後面或作為範圍的結束字元。

'^'
該字元表示不在列表中的字元。如果想匹配該字元的字面意義,則必須不能放在列表的第一個字元。

 

3.3 The Backslash Character and Special Expressions(反斜線字元和特殊的表示式)

反斜線""後使用特定的字元表示特殊意義,如下:

'b'
匹配單詞邊界處的空字元。 (註:grep中的單詞有數位、字母和下劃線組成,其他所有字元都是單詞的分隔符。)

'B'
和"b"相反,表示匹配非單詞邊界的空字元。

'<'
匹配單詞起始位置處的空字元。

'>'
匹配單詞結束位置處的空字元。

(註:所以bWORDb等價於<word>。另外,grep選項"-w"也表示匹配單詞邊界)

'w'
匹配單詞成分的字元。是[_[:alnum:]]的同義詞。

'W'
匹配非單詞成分的字元,是[^_[:alnum:]]的同義詞。

's'
匹配空白字元,是[[:space:]]的同義詞。

'S'
匹配非空白字元,是[^[:space:]]的同義詞。

例如,"bratb"匹配被分割後的"rat","BratB"匹配"crate"但不匹配"furry rat"。

 

3.4 Anchoring(錨定)

脫字元"^"以及美元符"$"是錨定元字元,分別匹配行首和行尾的空字元。

 

3.5 Back-references and Subexpressions(後向參照和子表示式)

反向參照"N"表示匹配前面第N個括號中的正則子表示式,其中N是單個數位。例如"(a)1"表示"aa"。當使用二選一的操作符"|"時,如果分組不參與匹配過程,則後向參照將失敗。例如"a(.)|b1"將無法匹配"ba"。 如果使用"-e"或"-f FILE"指定了多個PATTERN,則每個pattern的後向序列值都相互獨立。

(註:例如:'([ac])e1|b([xyz])2t'能匹配aea或cec,但不能匹配cea或aec,還能匹配bxxt或byyt或bzzt。但如果將"2"換成"1",即'([ac])e1|b([xyz])1t',將無法匹配b[xyz]at或b[xyz]ct,因為第一個括號在左邊,無法參與右邊的正則搜尋。

(註:反向參照也稱為後向參照或回溯參照)

 

3.6 Basic vs Extended Regular Expressions(基礎正則和擴充套件正則)

在基礎正規表示式中,元字元'?'、'+'、'{'、'|'、'(',和')'都表示字面意思,取而代之的是加上反斜線的版本:'?'、'+'、'{'、'|'、'('和')'。

 

4 Usage(使用範例)


以下是一些GNU grep的使用範例:

grep -i 'hello.*world' menu.h main.c

該命令用於列出menu.h和main.c中包含"hello"字串且後面帶有"world"字串的所有行,hello和world中間可以有任意多個字元。注意正規表示式的"-i"選項使得grep忽略大小寫,所以還能匹配"Hello, world!"。

下面是一些使用grep時常見的問題和答案。

  1. 如何列出匹配的檔名?

    grep -l 'main' *.c

    將列出當前目錄下所有以".c"結尾且檔案中包含'main'字串的檔名。

  2. 如何遞回搜尋目錄?

    grep -r 'hello' /home/gigi

    搜尋/home/gigi目錄下所有檔案,且檔案中包含'hello'字串。如果要靈活控制搜尋的檔案,可以??合find和xargs命令一起使用。例如下面的例子僅搜尋C原始檔。

    find /home/gigi -name '*.c' -print0 | xargs -0r grep -H 'hello'

    這不同於下面的命令:

    grep -rH 'hello' *.c

    這僅僅只是搜尋當前目錄下以".c"結尾的檔案。此處的"-r"選項基本上算是多餘的,除非當前目錄下有以".c"結尾的目錄,但這是很少見的情況。上面的find命令更類似於下面的命令:

    grep -rH --include='*.c' 'hello' /home/gigi
  3. 如果pattern以短橫線"-"開頭會如何?

    grep -e '--cut here--' *

    將搜尋"--cut here--"。但如果不給定"-e"選項,grep將可能把"--cut here"解析成一系列的選項。

  4. 如何搜尋整個單詞,而不是單詞中的一部分?

    grep -w 'hello' *

    這將搜尋當前目錄下所有檔案,並找出包含"hello"整個單詞的檔案,它無法匹配"Othello"。更靈活的控制可以使用"<"和">"來匹配單詞的開始和結尾。例如:

    grep 'hello>' *

    僅搜尋"hello"結尾的單詞,因此可以匹配"Othello"。

  5. 如何輸出匹配行的上下幾行?

    grep -C 2 'hello' *

    這將輸出匹配行以及它的前後兩行。

  6. 如何強制grep即輸出匹配行又輸出檔名? 只需在檔案列表中加上'/dev/null'即可。

    grep 'eli' /etc/passwd /dev/null

    將得到:

    /etc/passwd:eli:x:2098:1000:Eli Smith:/home/eli:/bin/bash

    還可以使用GNU擴充套件選項"-H":

    grep -H 'eli' /etc/passwd
  7. 為什麼有人在ps的後面使用奇怪的正規表示式?

    ps -ef | grep '[c]ron'

    如果pattern中不加上中括號,將匹配包含cron字串的進程,包括grep自身,因為grep命令的表示式中包含了cron字串。但如果加上了中括號,則grep命令列中包含的是"[c]ron"字串,而grep所匹配的字串是cron而不是[c]ron。 在輸出結果上,這其實等價於下面這條命令:

    ps -ef | grep 'cron' | grep -v 'grep'
  8. 為什麼grep的結果中會報告"Binary file matches"?
    如果grep列出二進位制檔案中的所有匹配行,將很可能生成一大堆亂七八糟的無用資訊,因此GNU的grep預設禁止這樣的輸出。如果想要輸出二進位制內容,使用"-a"或"--binary-files=text"選項。

  9. 為什麼'grep -lv'輸出的是包含非匹配行的檔名?
    'grep -lv'列出的是包含一行或多行非匹配行的檔名。如果想要列出無匹配內容的檔名,則使用"-L"選項。 (註:例如a.txt中一部分行匹配到了,一部分行沒匹配到,而b.txt中完全沒有匹配上,則grep -lv將輸出a.txt,而不是b.txt。因此可推測"-v"選項的操作優先順序要高於"-l",即先搜尋出反轉行,再輸出包含這些反轉行的檔案)

  10. 使用"|"可以實現or邏輯,如何實現AND邏輯?

    grep 'paul' /etc/motd | grep 'franc,ois'

    將搜尋出同時包含"paul"和"franc,ois"的所有行。

  11. 如何同時搜尋檔案和標准輸入?
    只需使用"-"代替標準輸入的檔名即可:

    cat /etc/passwd | grep 'alain' - /etc/motd
  12. 正規表示式中如何表達出回文結構?(註:回文結構表示正讀和反讀的結果是一樣的,例如12321,abcba)
    可以使用反向參照來實現。例如,一個4字元的結構使用BRE來實現:

    grep -w -e '(.)(.).21' file

    它可以匹配單詞"radar"或"civic"。 Guglielmo Bondioni提出了一個正規表示式,可以搜尋長達19個回文結構的字串,其中使用了9個子表示式和9個反向參照。因為BRE或ERE最多只支援9個反向參照。

    grep -E -e '^(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?).?987654321$' file
  13. 為何反向參照會失效?

    echo 'ba' | grep -E '(a)1|b1'

    這不會輸出任何內容,因為左邊的表示式"(a)1"無法匹配,因為輸入資料中沒有"aa",因此右邊的"1"無法參照任何內容,意味著將不匹配任何東西。(此例中右邊表示式僅在左邊表示式成功匹配時才能生效。)
    註:經測試,即使左邊表示式能匹配上,右邊表示式中參照左邊的分組時也無效。例如"echo 'baaca' | grep -E '(a)1|c1'"可以匹配大其中的"aa",但卻匹配不到"ca"。

  14. grep如何跨行匹配?
    標準的grep無法實現該功能,因為它是基於行讀取的。因此,僅僅使用字元類"[:space:]"無法如你想象中那樣匹配換行符。
    GNU的grep有一個選項"-z",它可以處理使用""結尾的行。因此,可以匹配輸入資料中的換行符,但通常很可能在輸出結果時,輸出的是所有內容而不僅是被匹配的行,因此經常需要結合輸出控制選項如"-q"來使用。例如:

    printf 'foonbarnabc' | grep -z 'foo[[:space:]]+bar'
    printf 'foonbarnabc' | grep -z -q 'foo[[:space:]]+bar'

    如果這還不滿足需求,可以將輸入資料進行格式轉換然後交給grep,或者使用其他工具替代grep,如"sed"、"awk"、"perl"或其他很多工具都能跨行操作。

  15. What do 'grep', 'fgrep', and 'egrep' stand for?
    The name 'grep' comes from the way line editing was done on Unix. For example, 'ed' uses the following syntax to print a list of matching lines on the screen:

    global/regular expression/print  
    g/re/p

    'fgrep' stands for Fixed 'grep'; 'egrep' stands for Extended 'grep'.

 

5 Known Bugs(已知的一些bug)


當"{n,m}"指定的重複次數很多時,將導致grep消耗大量記憶體。此外,越模糊的正規表示式消耗的時間和空間越多,也會讓grep消耗大量記憶體。 反向參照的功能非常慢,因此可能會消耗大量時間。 (註:遞回搜尋時,也會消耗巨量的記憶體,很容易提示記憶體溢位錯誤而提前退出。)

本文永久更新連結地址http://www.linuxidc.com/Linux/2017-09/146645.htm


IT145.com E-mail:sddin#qq.com