grep 命令詳解

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

(1)
guli3057guli3057
上一篇 2016-02-14
下一篇 2016-02-14

相關推薦

  • Linux運維學習歷程-第十一天-bash邏輯運算、測試類型和腳本語句

    概述:本篇重點介紹linux當中默認設立了類型,bash的邏輯運算、測試類型和腳本語句,本篇內容極其重要,望小伙伴們在日后的學習中用心學習 一、邏輯運算 變量:   本地變量、環境變量、局部變量、位置參數變量、特殊變量   變量賦值:name=value,export name=value,declare -x nam…

    Linux干貨 2016-08-24
  • Linux之高級文件系統管理

      Linux之高級文件系統管理       Linux高級文件系統管理包括以下內容   一, 磁盤配額quota管理二, 磁盤陣列RAID管理三, 邏輯磁盤LVM管理四, 磁盤LVM快照管理五, Btrfs文件系統管理         配置磁盤配額系統 在內核中執行以…

    Linux干貨 2016-09-02
  • 基于NFS實現WordPress

    實驗內容: (1)主機IP nfs server IP :192.168.29.120 nfs server IP: 192.168.29.110 (2)要求 nfs server共享/data/web/ 、/data/mysql 兩個目錄 nfs client掛載nfs server共享的/data/web/的文件系統至/var/www/html;部署wo…

    2017-06-13
  • btrfs管理及應用

    一. 簡介     btrfs有著強大的功能,它支持在多個及各種物理設備(包括RAID)上創建一個文件系統,并支持動態擴展或減小,支持快照功能,甚至快照的快照,支持子卷功能。 二. 如何使用btrfs文件系統?     我的準備材料:3塊20G的硬盤 [root@localhost ~]#…

    Linux干貨 2015-12-07
  • N26-第四周

    1、復制/etc/skel目錄為/home/tuser1,要求/home/tuser1及其內部文件的屬組和其他用戶均沒有任何訪問權限。[root@localhost home]# cp -R /etc/skel/ /home/tuser1 && chmod -R g=,o= /home/tuser1 [root@localhost …

    Linux干貨 2017-03-07
  • shell腳本編程之判斷語句

    一、單分支if語句     格式:if 判斷條件;then        statement1        statement2          …     &nb…

    Linux干貨 2016-01-01

評論列表(1條)

  • stanley
    stanley 2016-02-14 10:05

    分類清晰明了

欧美性久久久久