grep, egrep, fgrep

显示匹配模式的文本行


语法格式

grep [-abcEFGhHiLnoPqRsrtvwxzZ] [gnu-opts] pattern [files]
grep [-abcEFGhHiLnoPqRsrtvwxzZ] [gnu-opts] [-e pattern|-f file] [files]
grep [--help] [-V|--version]

命令简介

grep用于读取输入文件或标准输入,按照指定的模式检索匹配的字符串。一旦检索到匹配的字符串,grep通常会输出相应的数据行。

其中,pattern是正则表达式检索模式,用于选择匹配的字符串,files是一个或多个数据文件。如果未指定文件,或指定的文件为“-”,则使用标准输入作为输入文件。

此外,grep存在两个变体:egrep和fgrep命令。egrep命令相当于“grep -E”,fgrep命令相当于“grep -F”。前者采用扩展的正则表达式解释匹配模式,后者按照匹配模式的字面意思即文字本身解释匹配模式。egrep和fgrep将会逐渐隐退,需要时可用grep的相应选项代之。当然,系统通常还会提供,以便传统的应用能够不加修改地继续运行。

命令选项(匹配类型选择)

-E, --extended-regexp  按照扩展的正则表达式解释指定的模式参数。运行“grep -E”相当于直接运行egrep命令。

-F, --fixed-strings  把模式参数看作一组字符串(而非模式),按照字符的文字本身检索匹配的数据。运行“grep -F”相当于直接运行fgrep命令。

-G, --basic-regexp  按照基本的正则表达式解释指定的模式参数(默认的选项)。

-P, --perl-regexp  按照Perl正则表达式解释指定的模式参数(尚未完全实现)。

命令选项(匹配控制)

-e pattern, --regexp=pattern  使用指定的模式作为检索模式。利用这个选项可以指定多个检索模式,也可以指定首字符为连字符“-”的模式。

-f file, --file=file  从指定的文件中读取模式,其中每行包含一个模式。如果模式文件为空,意味着包含零个模式,因而不匹配任何行。

-i, --ignore-case  忽略模式参数或输入文件中模式的大小写字母差别。

-v, --invert-match  反向匹配,即选择不匹配模式参数的数据行。

-w, --word-regexp  仅选择匹配模式参数的字符串是一个完整字的数据行。一个字由大小写字母、数字和下画线组成。

-x, --line-regexp  仅选择整行能够完全匹配模式参数的数据行。

命令选项(通用输出控制)

-c, --count  仅仅输出每个输入文件中匹配模式参数的数据行的数量,而不是输出匹配的数据行。当与“-v”选项一起使用时,仅输出不匹配的数据行的数量。

--color[=when], --colour[=when]  围绕匹配的非空字符串、匹配的数据行、相关数据行、文件名、行号、字节偏移值以及字段与相关行组分隔符等,增加转义字符序列,以彩色(由GREP_COLORS环境变量定义)形式在终端屏幕上显示。when的取值是never(不加彩色)、always(总是增加彩色)或auto(视终端而定)。

-l, --files-with-matches  仅仅输出每个包含匹配数据的输入文件名。

-L, --files-without-match  仅仅输出每个不包含匹配数据的输入文件名。

-m num, --max-count=num  在发现指定数量的匹配数据行之后停止检索。如果输入数据来自普通的文本文件,grep在输出指定数量的匹配数据行之后,终止运行之前将会记住最后一个匹配位置,当再次运行grep命令时能够从断点处恢复检索。当与“-v”选项一起使用时,在输出指定数量的不匹配数据行之后grep也会停止运行。

-o, --only-matching  仅仅输出恰好匹配的部分(非空)。每个匹配部分分行输出。

-q, --quiet, --silent  安静输出模式,即不输出任何信息,包括匹配的数据行和错误信息。检索结束或遇到错误后立即退出。如果发现任何匹配,返回结束状态0,其他情况返回非零的结束状态。参见“-s”选项。

-s, --no-messages  禁止输出错误信息,即使输入文件不存在或无法读取文件。但不禁止输出匹配的数据行,这一点与“-q”选项不同。

命令选项(输出数据行的前缀控制)

-b, --byte-offset  在输出的每一行之前,插入一个字节偏移值,表示含有匹配数据行的第一个字符在输入文件中的字节位置(从零开始编号)。如果同时指定了“-o”选项,则表示匹配字符串的第一个字符在输入文件中的字节位置。

-h, --no-filename  禁止在输出的匹配数据行之前冠以文件名前缀。当仅检索一个输入文件时,这是默认的做法。

-H, --with-filename  显示每个匹配数据行所在文件的名字。当同时检索多个输入文件时,这是默认的做法。

-n, --line-number  在输出的每个匹配的数据行之前插入一个行号前缀。行号是数据行在输入文件中的逻辑行号,从1开始编号。

-T, --initial-tab  确保数据行实际内容的第一个字符处于制表符位置。当使用 “-H”、“-n”或“-b”选项在数据行之前增加文件名、行号或字节偏移值前缀时,这个选项是非常有用的。

-Z, --null  以NULL字符替代常规的文件名终止符(换行符)输出文件名。例如,“grep -lZ”命令在输出文件名时使用NULL字符替代换行符作为文件名的终止符。这个选项可与“find -print0”、“perl -0”、“sort -z”和“xargs -0”等命令一起配合使用,以处理任何类型的文件名,即使其中包含换 行符。

命令选项(相邻行控制)

-A num, --after-context=num  输出匹配的数据行之后,再输出其后面的数行数据。当存在多个匹配的数据行时,在每组数据行之间输出一个分隔符“--”。与“-o”选项一起使用时,这个选项不起作用,而且会输出一条警告信息。

-B num, --before-context=num  在输出匹配的数据行之前,先输出其前面的数行数据。当存在多个匹配的数据行时,在每组数据行之间输出一个分隔符“--”。与“-o”选项一起使用时,这个选项不起作用,而且会输出一条警告信息。

-C num, -num, --context=num  围绕匹配的数据行,输出其相邻的数行数据。当存在多个匹配的数据行时,在每组数据行之间输出一个分隔符“--”。与“-o”选项一起使用时,这个选项不起作用,而且会输出一条警告信息。

命令选项(目录与文件选择)

-a, --text  就像处理文本文件一样处理二进制数据文件。

-d action, --directories=action  如果输入文件参数是一个目录,按照action的要求进行处理。通常,action是read,意味着像读普通文件一样读取目录。如果action是skip,意味着不动声色地跳过即可。如果action是recurse,意味着递归地读取每个目录中的所有文件。相当于“-r”选项。

-D action, --devices=action  如果输入文件参数是一个设备文件、管道文件或套接字,按照action的要求进行处理。通常,action是read,意味着像读普通文件一样读取设备文件等。如果action是skip,意味着不动声色地跳过设备文件等即可。

--exclude=glob  跳过其基本名字(不含目录部分)匹配指定通配符模式glob的文件。所谓的通配符模式指的是含有“*”、“?”或“[...]”的文件名模式。

--exclude-dir=dir  从递归检索中排除匹配指定的目录。

--exclude-from=file  跳过其基本名字(不含目录部分)匹配指定文件file提供的任何通配符模式的文件。

--include=glob  仅检索其基本名字(不含目录部分)匹配指定通配符模式glob的文件。

-R, -r, --recursive  递归地读取每个目录中的所有文件。相当于“-d recurse”选项。

命令选项(其他选项)

--mmap  尽可能使用mmap(2) 读取输入数据,而不是使用read(2)系统调用(默认)读数据,在某些情况下,“--mmap”选项能够表现出较好的性能。

-z, --null-data  用于检索行终止符为NULL字符而非换行符的数据文件。类似于“-Z”选项,这个选项可与“sort -z”等命令一起配合使用,以处理任何类型的文 件名。

正则表达式

正则表达式提供一种机制,用于从一组字符串中选择特定的字符串。简单地说,正则表达式是一种字符串匹配模式或特性描述,用于选择与之匹配的字符串。

grep能够处理3种不同类型的正则表达式:基本正则表达式(BRE)、扩展正则表达式(ERE)和perl正则表达式。有关perl正则表达式的解释详见perl命令的说明,这里仅介绍BRE与ERE。

正则表达式具有下列特点:

基本正则表达式(BRE)

普通字符  除了BRE的特殊字符之外,字符集中的任何字符都是普通字符。如果加上转义符号“\”前缀,特殊字符也是普通字符。作为最基本的正则表达式,任何一个普通字符都能够匹配自身。例如,a能够匹配a本身,“\*”能够匹配“*”本身,abcdefg能够匹配字符串abcdefg。

特殊字符  BRE支持“.”、“[”、“\”、“*”、“^”和“$”6个特殊字符。在一定的上下文环境中,特殊字符具有特殊的意义。如果出现在表达式的不同位置,或在前面加上转义符号前缀,就不是特殊字符,因而同普通字符一样,能够匹配自身。例如,如果出现在方括号表达式之内,任何特殊字符都只是一个普通字符。

.  句点匹配任意一个单字符,但唯独不能匹配NULL字符。例如,“.ould”能够匹配could或would等字符串,“.*可以匹配任何一个字符串,包括空串。
[  左方括号是方括号表达式的起始标志。
\  转义符号,用于引用特殊字符(包括自身),以及“(”、“)”、“{”、“}”和数字1~9。在BRE中,上述字符只是普通字符,如果加上转义符号前缀,就有了特殊意义。其中,“(”与“)”用于构造子表达式,“{”与“}”用于构造区间表达式,数字1~9用于反向引用。
*  用于重复匹配先前的表达式,但如果出现在方括号表达式之内,或者作为整个表达式(或子表达式)的首字符,“*”只是一个普通字符(如果首字符为“^”,紧随其后的也是如此)。
^  用作位置表达式或方括号表达式的首字符。如果出现在其他位置,包括在方括号表达式内的其他位置,“^”只是一个普通字符。
$  用作位置表达式。如果出现在其他位置,“$”只是一个普通字符。

方括号表达式与字符类

[ ]  方括号表达式用于定义一个字符集合,可用于匹配其中的任何一个单字符。如果字符集合中的第一个字符是箭头字符“^”,表示可以匹配不在其中的任何一个单字符。例如,表达式“[0123456789]”用于匹配任何一个数字,“[^0123456789]”可用于匹配任何非数字字符。在方括号表达式中,可以使用“char1-char2”形式的字符范围表达式定义一个字符集合或类别,可用于匹配指定字符范围中的任何一个单字符。例如,“[0-9]”等同于“[0123456789]”。此外,方括号表达式还支持“[:class:]”、“[=a=]”以及“[.ch.]”形式的字符类、等价类和排序符号等,如[:alnum:]、[:alpha:]、[:cntrl:]、[:digit:]、[:graph:]、[:lower:]、[:print:]、[:punct:]、[:space:]、[:upper:]以及[:xdigit:]等。这些字符类均可按其字面意思解释,例如,[[:alnum:]]意味着[0-9A-Za-z]。在方括号表达式中,大部分特殊字符都失去特殊含义,作为普通字符处理。例如,表达式“[.(\*^$]”是一个特殊字符的集合,用于匹配任何特殊字符本身。此外,如果想把“]”作为字符集合中的一个普通字符,可将其作为字符集合的第一个字符。类似地,可以把箭头字符“^”放在字符集合中除第一个字符位置之外的其他任何字符位置,把连字符“-”放在字符集合中的最前或最后一个字符位置,如此等等。

连接  用于连接两个或多个表达式。连接后的表达式能够匹配表达式各自匹配的字符串的连接。例如,表达式abc能够匹配字符串abc,表达式edf能够匹配字符串def,表达式的连接abcdef能够匹配字符串abcdef。

子表达式与反向引用

\( \)  一个表达式如果出现在加转义符号的一对圆括号之内,这样的表达式称作子表达式。例如,“\(abc\)”表示abc是一个子表达式,加转义符号的圆括号只是一个记号,不是表达式的一部分。一个表达式中可以存在多个子表达式,子表达式从1开始编号。
\i  反向引用(back reference)。i是1~9中的一个数字,表示匹配正则表达式中第i个子表达式选择的子串。例如,“^\(.*\)\n\1$”表示匹配由两个等同子串中间加换行符组成的字符串。

区间表达式  表达式后面可以加一个区间表达式,表示重复匹配前面的表达式。

*  匹配前一项0次或多次。例如,ap*le匹配ale或apple等。
\{m\}  
匹配前一项恰好m次。m是一个整数。例如,“[0-9]{6}”表示恰好匹配6位 数字。
\{m,\}
匹配前一项m次或m次以上。
\{,n\}
匹配前一项最多n次(包括n本身)。
\{m,n\}
匹配前一项至少m次,但不超过n次(包括mn本身)。

位置表达式

^  匹配行首的空串,即匹配行首的任何字符或字符串。例如,“^#”匹配行首以“#”为起始字符的字符串,如“#include”。
$  匹配行尾的空串。例如,“\\$”表示匹配任何以单个反斜线“\”(行延续符)结尾的数据行。“\.$”表示匹配任何以句点“.”结尾的数据行。

BRE的优先顺序(从高到低)

字符类与等价类等  [==] [::] [..]

转义字符  \^ \. \* \[ \$ \\

方括号表达式  []

子表达式与反向引用  \( \) \n(其中n是1~9)

重复  * \{m,n\}

连接  regex1regex2

位置表达式  ^ $

扩展正则表达式

普通字符  说明同BRE。

特殊字符  ERE支持“.”、“[”、“\”、“*”、“^”、“$”、“(”、“)”、“{”、“+”、“?”和“|”这12个特殊字符。如果加上转义字符前缀,或出现在方括号表达式之内,则这些特殊字符都失去特殊含义,只是一个普通字符。参见BRE中的说明。下面是对新增特殊字符的补充说明(其他特殊字符的意义同BRE,说明从简,仅列存目):

.  句点匹配任意一个单字符,但唯独不能匹配NULL字符。
[  左方括号是方括号表达式的起始标志。
\  转义符号,用于引用特殊字符(包括自身)。
*  用于重复匹配先前的表达式。
^  用作位置表达式,或方括号表达式的首字符。
$  用作位置表达式。
()  圆括号用于组合表达式,把其中的表达式作为一个整体表达式处理。
{  左圆括号是花括号重复表达式的起始标志。
+  用作1次或多次表达式重复的记号。
?  用作0次或1次表达式重复的记号。
|  用作交替匹配表达式的记号。

方括号表达式与字符类别

说明同BRE。

连接  说明同BRE。

组合表达式

( )  把多个表达式置于一对圆括号之内,可以作为一个表达式的整体解释与处理。但圆括号只是一个记号,不是表达式的一部分。一个表达式中可以存在多个组合表达式。例如,表达式“abc*”能够匹配ab、abc、abcc等字符串,但表达式“(abc)*”只能匹配空串、abc或abcabc等字符串。

区间表达式  表达式后面可以加一个区间表达式,表示重复匹配前面的表达式。除了“*”与“{}”区间表达式之外,ERE又增加了“?”与“+”两个区间表达式,补充说明如下(其他区间表达式的意义同BRE,说明从简,仅列存目):

?  匹配前一表达式0次或1次。前一项必须是一个普通字符、一个转义字符、一个句点“.”、一个正则表达式或一个方括号表达式。例如,“index\.html?”能够匹配index.html或index.htm,“script(\.sh)?”能够匹配script或script.sh等。
*  匹配前一项0次或多次。
+  匹配前一表达式1次或多次。例如,“a+b+”能够匹配1个或多个a,后面跟随1个或多个b,其中ab是最短的匹配,其他可以是aab或abb等。“.+”能够匹配任何一个字符串,但每个字符串至少必须包含一个字符,即不匹配空串。
{m}  匹配前一项恰好m次。m是一个整数。
{m,}  匹配前一项m次或m次以上。
{,n}  匹配前一项最多n次(包括n本身)。
{m,n}
匹配前一项至少m次,但不超过n次(包括mn本身)。

位置表达式  说明同BRE。

交替匹配  re1|re2

交替匹配。选择匹配re1或匹配re2的字符串。例如,“(Q\|q)uit”表示Quit或quit都是可选择的匹配字符串。

ERE的优先顺序(从高到低)

字符类与等价类等  [==] [::] [..]
转义字符  \^ \. \* \[ \$ \\ \( \) \| \+ \? \{
方括号表达式  []
组合  ()
重复  * + ? {m,n}
连接  regex1regex2
位置表达式  ^ $
交替匹配  |

BRE与ERE之间的区别

grep支持BRE与ERE,除非指定了“-E”选项,grep默认支持的是BRE。当检索结果超出预期时,首先要弄清楚是否混用了BRE与ERE。下面是两者之间的主要差别:

特殊表达式

除了正则表达式,grep也支持下列特殊的表达式:

\<  匹配字首的空串。例如,“\<wo”能够匹配word、world和would等单词。

\>  匹配字尾的空串。例如,“it\>”能够匹配exit、Exit、quit和Quit等单词。

\b  匹配单字左右边缘字符的空串。例如,“\ba”能够匹配age或air等单词,“e\b”能够匹配same或come等单词。

\B  匹配单字非边缘字符的空串。例如,“\Bm”或“m\B”能够匹配same或come等单词。

\w  等同于“[[:alnum:]]”,匹配任何字母或数字。

\W  等同于“[^[:alnum:]]”,匹配非字母数字的任何字符。

应用实例

1. 从指定的目录开始递归地检索其中的所有文件,找出含有匹配指定关键字模式的文件与数据。

$ grep -r 'LIMIT' /usr/include

2. 检索当前目录中的所有文件,找出哪个文件含有匹配指定模式的单字,而不是字符串中的子串。

$ grep '\<name\>' *

索引: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