grep 命令詳解
概述:本文檔基于 info grep 翻譯,完成度可能 90% 左右。
作者:N10-guli
時間:2016-01-05
版本:v1.0
目錄:
1,grep 命令的選項
2,grep 命令的正則表達式
3,grep 命令使用示例
1,grep 命令的選項
1.1 概念
grep 從輸入的文件中,尋找與 pattern list 匹配的行。 因為換行符也是 pattern list 的分隔符,所以不可能對換行符做匹配。
1.2 調用 grep 的語法
grep OPTIONS.. PATTERN INPUT_FILE_NAMES.. 除了這種寫法,pattern 也可以由 -e PATTERN 給出,或者從文件中讀取 pattern -f FILE 。 省略號 .. 表示可以有多個
1.3 命令行選項
grep 命令有許多選項,來自 POSIX.2 和 GNU 的擴展。 長選項通常是 GNU 的擴展,短選項由 POSIX 指定。
1.3.1 普通的程序信息
--help 幫助 -V, --version 打印版本號
1.3.2 匹配控制
-e PATTERN, --regexp=PATTERN 可指定多個 PATTERN, 或用于保護以 - 開頭的 PATTERN -f FILE, --file=FILE 從 FILE 中獲取 PATTERN, 一行為一個??瘴募裁炊疾黄ヅ洹? -i, --ignore-case 忽略大小寫 -v, --invert-match 找出不匹配的行 -w, --word-regexp 整詞匹配,匹配的字符串的前后不能是 字母,數字或下劃線。 -x, --line-regexp 整行匹配
1.3.3 總體輸出控制
-c, --count 打印每個文件中匹配的行數 --color[=WHEN] grep 結果的顏色控制,WHEN=never, always, auto 顏色由 GREP_COLORS 設置。 -L, --files-without-match 只打印沒有匹配行的文件的文件名 -l, --files-with-matches 只打印有匹配行的文件的文件名 -m NUM, --max-count-NUM 匹配到了 NUM 行,就停止。 while grep -m 1 PATTERN do echo xxxx done < FILE 這個腳本的含義是:在 FILE 中每匹配一行,執行一次 echo xxx。 與 -c 配合,輸出必然小于等于 NUM 與 -v 配合,輸出不匹配的行,最多 NUM 行。 -o, --only-mathing 只打印匹配的部分,而非整行 -q, --quit, --silent 如果有匹配的行,立即結束進程,返回 0 狀態值,不輸出任何信息。 -s, --no-messages 當遇到不存在的文件,或不可讀的文件時,不打印錯誤。 為了腳本的可移植性,建議重定向標準輸出和錯誤輸出。
1.3.4 輸出行的前綴控制
打印多個前綴字段時,順序是固定的:文件名,行序號,字節偏移 以冒號':'分隔。 -b, --byte-offset 打印每一行的字節偏移(0-based)。 帶了 -o 選項時,只計算匹配字符串的偏移。 -H, --with-filename 有多個文件輸入時,默認帶有 -H 選項。 在每一個匹配行之前,打印文件名前綴 -h, --no-filename 單個文件輸入時,默認帶有 -h 選項。 不打印文件名前綴。 --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-based) -T, --initial-tab 使用 tab 使行盡可能對齊。 -u, --unix-byte-offsets 配合 -b 使用,使在 MS-DOW, MS-Windows 的輸出與 Unix 環境相同 -Z, --null 在文件名后使用 zero byte(ASCII 的 NUL 字符)代替換行符 grep -lZ FILE 輸出的文件名以 nul 結尾。 配合 find -print0, sort -z, xargs -0, perl -0, 即使文件名含有特殊字符如 換行符,也能正確處理。
1.3.5 文本行控制
所有輸入的行在輸出中只會打印一次。相鄰的輸出有重合時,自動合并。 注意:以下的選項在使用 -o 選項后失效 -A NUM, --after-contex=NUM 打印匹配行以及其后的 NUM 行 -B NUM, --before-contex=NUM 打印匹配行以及其前的 NUM 行 -C NUM, -NUM, --contex=NUM 打印匹配行以及之前,之后的 NUM 行 --group-separator=STRING -A, -B,—C 的輸出,以 -- 分隔不同的組 這個選項可設置為以 STRING 分隔 --no-group-separator 不同的組,不做分隔
1.3.6 文件和目錄選項
-a, --text 把二進制文件當做文本文件處理,有可能輸出垃圾信息,產生邊際效應。 (輸出的信息被終端解釋為其他命令) 等同于 --binary-files=text --binary-files=TYPE 如果文件首部的字節指示這是一個二進制文件,當 TYPE=binary(默認值): 有匹配時,輸出一條消息,說明匹配了 無匹配時,沒有輸出 TYPE=without-match: 假定沒有匹配,與 -I 相同 TYPE=text 與 -a 相同,將其當做 文本文件處理 -D ACTION, --devices=ACTION 輸入文件為 device, FIFO, socket 時。 使用 ACTION 處理。默認為 read, 正常讀取。 如果為 skip, 這類文件被跳過,不做處理。 -d ACTION, --directories=ACTION 輸入文件為 目錄時,使用 ACTION 處理。 默認為 read, 將目錄文件當做普通文件讀取。 skip: 跳過 recurse: 目錄下的文件都被遞歸地讀取, 同于 -r --exclude=GLOB GLOB 使用通配符匹配文件名:*, ?, [], [^], \ 反斜線可以使通配符變為普通字符。 跳過匹配的文件名,不做處理 --exclude-from=FILE 從文件中讀取要跳過的 GLOB --exclude-dir=DIR DIR 為 PATTERN 匹配的 dir 不做遞歸讀取 -I 二進制文件當做不匹配處理 --include=GLOB 只處理 GLOB 匹配的文件。 GLOB 是通配符 -r, -R, --recursive 命令行中的每一個目錄,對其中的所有文件讀取并處理, 其中還有目錄的話,繼續做遞歸處理。
1.3.7 其他選項
--line-bufferd 在輸出時使用 line buffering --mmap 讀取輸入時,使用 mmap 代替 read 函數 -U, --binary 僅在 MS-DOS, MS-Windows 有效。 grep 會通過文件 首部的32KB,猜測文件類型。 如果認為是 文本文件,會除去 CR 字符。 -U 會跳過猜測步驟而直接讀取,這樣遇到 CR/LF 結尾時可能使匹配出錯 -z, --null-data 把輸入的行看做以 NUL 結尾的行(正常是以 newline 結尾)進行處理。
1.4 環境變量
grep 的使用受到以下 環境變量 的影響 LC_FOO 類的變量與三個變量的值有關系,依次檢查 LC_ALL, LC_FOO, LANG, 以第一個非空的變量值作為 LC_FOO 的值。如果都是空值,或者 locale 目錄沒有安裝, 或者 grep 程序沒有在編譯時加入 國際語言 支持,這時就使用 C 作為變量值。 GREP_OPTIONS 指定默認選項,選項之間以空格分隔,默認選項放在顯式給出的選項之前。 選項含有 \ 或者空格時,使用 \ 反斜線 轉義空格和 \, GREP_COLOR 已過時,但仍被支持 指定匹配部分的高亮顏色,默認為 01;31,加粗,紅色前景色。 GREP_COLORS 指定輸出的高亮顏色。 默認值為(以冒號作為分隔符) ms=01;31:mc=01;31:sl=:cx=:fn=35:ln=32:bn=32:se=36 這部分太長,沒有翻譯了。 LC_ALL LC_COLLATE LANG 影響 [a-z] 的表示意義。 LC_ALL LC_CTYPE LANG 指定 字符類型。如,哪一個字符表示 空格。 LC_ALL LC_MESSAGES LANG 指定 grep 產生的消息使用的語言 默認為 C 表示使用美國英語。 POSIXLY_CORRECT grep 的行為更符合 POSIX.2 的要求。 默認是 GNU 的風格。 POSIX.2 要求文件名后的 選項,被當做文件名看待,GNU 則將之重新排列,仍視為選項 POSIX.2 要求不能識別的選項被判斷為 非法,GNU 則判斷為 無效 _N_GNU_nonoption_argv_flags_ (N 為 grep 的進程 ID 號) 如果變量值的第 I 個字符為 1,則 grep 的第 I 個操作數將不被認為是 操作數。 用于防止文件名通配符的展開,被誤認為選項。 此行為只在 GNU C library 支持下有效。 POSIXLY_CORRECT 禁用此選項。
1.5 退出狀態值
正常情況下,如果有匹配的行,狀態返回值為 0, 否則為 1。 有錯誤發生時,返回 2,除非帶有 -q, 或 --quiet, 或 --silent 選項,并且有匹配的行。 Note, however, that POSIX only mandates, for programs such as `grep', `cmp', and `diff', that the exit status in case of error be greater than 1; it is therefore advisable, for the sake of portability, to use logic that tests for this general condition instead of strict equality with 2.
1.6 grep 程序
grep 從輸入的文件中(- 或者沒有輸入文件名時,表示從標準輸入中讀取) 尋找與 PATTERN 匹配的行。 有四種不同的 grep 程序,由以下選項控制選取。 -G, --basic-regexp 以基本正則的語法解釋 pattern。這是默認選項。 -E, --extended-regexp 以擴展正則的語法解釋 pattern。 -F, --fixed-strings 將 pattern 視為匹配固定的字符串,不同的 pattern 以 換行符分隔 -P, --perl-regexp 實驗中的選項。以 Perl 正則的語法解釋 pattern egrep 等同于 grep -E fgrep 等同于 grep -F 這兩個命令已經過時,不建議使用。但仍被支持。
2,grep 的正則表達式
正則表達式通過一個 pattern 描述一組字符串。 grep 支持三種正則表達式: 1,基礎正則,BRE 2,擴展正則,ERE 3,perl 正則 對于 GNU 的 grep,基礎正則與擴展正則的功能沒有區別。 在其他的實現中,基礎正則的功能一般會弱一些。 以下的描述適用于 擴展正則,其與 基礎正則的區別在后面會給出總結。 perl 正則提供更多功能,可參考 pcresyntax(3), pcrepattern(3) 的文檔。 可能不適用于每一個系統。
2.1 基本結構
正則表達式基礎的部分:單個字符的匹配。 大部分字符在正則表達式中代表其本身。 元字符是有特殊意義的字符,使用反斜線 \,可以使其失去特殊意義,代表其本身。 .匹配任意單個字符 ?此符號前面的字符可出現 0 次 或 1 次 * 此符號前面的字符可出現 0 次 或 多次 +此符號前面的字符可出現 1 次 或 多次 {N} 此符號前面的字符剛好出現 N 次 {N,} 此符號前面的字符出現 N+ 次 {,M} 此符號前面的字符出現 0~M 次 {N,M} 此符號前面的字符出現 N~M 次 兩個正則表達式可以進行串聯,最終匹配的字符串,由分別匹配兩個 正則表達式的字符串連接而成。 兩個正則表達式可以進行并聯,EXPR | EXPR,表示匹配其中一個 重復的優先級高于串聯,這兩者的優先級又高于并聯。 也可使用(),改變優先級關系,()中的表達式優先做處理。
2.2 字符分類和括號表達式
[LIST] 表示 LIST 字符列表中的任意一個 [^LIST] 表示 LIST 字符列表之外的任意一個 [0123456789] 表示任意一個數字 在默認的 C locale 中,[a-d] = [abcd] 在其他的 locale 中,[a-d] 可能等于 [aBbCcDd] 可設置 LC_ALL 為 C,保證是傳統的解釋 [a-d]=[abcd]。 以下是一些以名字分類的字符集,其解釋依賴于 LC_CTYPE 以下是 LC_CTYPE=C 時的解釋 大多數 元字符 在 [] 中失去其特殊含義,變為普通字符。 比較特殊的是 ']', '[]]' 匹配 ']' 字符,']' 必須放在中括號中的第一個位置 [:alnum:] 所有字母(包括大小寫字母,下同)和數字 [:alpha:] 所有字母 [:blank:] 空格,制表符 [:digit:] 所有數字 [:graph:] 所有字母,數字,標點符號 [:lower:] 所有小寫字母 [:upper:] 所有大寫字母 [:print:] 所有字母,數字,標點符號,空格 [:punct:] 所有標點符號: ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~ [:space:] 制表符,換行符,垂直制表符,跳頁, 回車,空格 [:xdigit:] 16進制字符 0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f
2.3 反斜線和特殊表達式
\b 匹配單詞邊緣的空字符串 \B 匹配非單詞邊緣的空字符串 \<匹配詞首的空字符串 \>匹配詞尾的空字符串 \w與 [[:alnum:]] 同義,匹配一個單詞 \W與 [^[:alnum:]] 同義,匹配非單詞字符組成的一個單詞 \brat\b 匹配獨立的單詞 rat \Brat\B 匹配 crate,不匹配 furry rat
2.4 錨定
^ 和 $ 是元字符,匹配行首和行尾的空字符串
2.5 反向引用和子表達式
\N,引用第 N 個() 匹配的內容。 (a)\1 匹配 aa 當使用 -e 或 -f 指定多個正則表達式,反向引用的有效范圍限定于當前表達式
2.6 基本正則 vs 擴展正則
在基本正則中,?,+,{,},|,(,) 失去了特殊意義 使用:\?, \+, \{, \}, \|, \(, \) 傳統的 egrep 不支持 { 元字符,有一些支持 \{ 元字符。 所以,可移植的腳本應該避免在調用 grep -E 時使用 { 元字符。 使用 [{] 可以使其失去特殊意義,匹配 { 字符 GNU grep -E 支持傳統的用法,如果 { 沒有成對使用 grep -E '{1' 將會匹配 '{1' 字符串,而不是報錯。 POSIX.2 允許這種擴展,但是為了可移植性,應避免使用。
3,grep 使用示例
1, 只輸出有匹配的文件的文件名 grep -l 'main' *.c 列出含有 main 的 C 文件名 2,如何遞歸地搜索目錄 grep -r 'hello' /home/gigi 進一步限定搜索范圍,可以使用 find, xargs 配合 grep: find /home/gigi -name '*.c' -print0 | xargs -r0 grep -H 'hello' 與之類似: grep -rH --include='*.c' 'hello' /home/gigi 下面這條命令與上面的命令不同,它的搜索范圍限于當前目錄: grep -rH 'hello' *.c 3,如果 pattern 以 - 開頭怎么辦? grep -e '--cut here --' * 如果這里不加 -e,grep 嘗試將 pattern 解釋成一組選項 4,假如我想搜索整個單詞,而不是單詞的一個部分該如何做? grep -w 'hello' * 這條命令不會匹配 Othello,只會匹配單獨的單詞 hello。 使用 '\<' 和 '\>' 可以分別匹配詞首和詞尾,比如 grep 'hello\>' * 這會匹配以 hello 結尾的單詞,比如 Othello。 (做整詞匹配的單詞兩旁相鄰位置不應該有 數字,字母,下劃線,這些被定義為單詞成分) 5,查看匹配行前面的行和后面的行 grep -C 2 'hello' * 6,在輸出行加上文件名前綴 加上 /dev/null grep 'sshd' /etc/passwd /dev/null GNU 中可以使用 -H: grep -H 'sshd' /etc/passwd 7,為什么在過濾 ps 的輸出,會有奇怪的正則? ps -ef | grep '[c][/c]ron' 如果不加 [],會輸出 grep 進程那一行。 8,為什么 grep 報告 Binary file matches 如果 grep 輸出一個二進制文件的匹配行,一般是無用的信息。 所以 grep 默認不輸出匹配信息。 強制輸出,使用 --binary-files=text 消除 "Binary file matches" 信息,使用: -I 或者 --binary-files=without-match 9,為什么 grep -lv 不打印沒有匹配行的文件的文件名? grep -lv 列出含有一個或多個不匹配行的文件名,這個文件中可能還有匹配的行。 列出沒有匹配行的文件名,使用: grep -L 或者 grep --files-without-match 10,使用什么表示 and 關系 grep 'paul' /etc/motd | grep 'franc,ois' 調用兩次 grep 11,如何同時從 標準輸入和文件中讀取 使用特殊文件名 - cat /etc/passwd | grep 'alain' - /etc/motd 12,從 ifconfig 輸出中抓取 ipv4 地址(添加的例子,僅供參考) ifconfig | grep -E "([0-9]|2[0-4][0-9]|25[0-5]|[1-9][0-9]|1[0-9][0-9])\.([0-9]|2[0-4][0-9]|25[0-5]|[1-9][0-9]|1[0-9][0-9])\.([0-9]|2[0-4][0-9]|25[0-5]|[1-9][0-9]|1[0-9][0-9])\.([0-9]|2[0-4][0-9]|25[0-5]|[1-9][0-9]|1[0-9][0-9])"
原創文章,作者:guli3057,如若轉載,請注明出處:http://www.www58058.com/10903
分類清晰明了