一、grep起源

二、grep用处

三、grep使用

    PATTERN是一个普通字符串

    PATTERN是一个正则表达式

    基本正则表达式

    扩展正则表达式



PS:为了能更好的学习每一个知识,我在每一个知识点后面都有加一个例子,自己多多动手,多多练习,这样效果才会更好。

一、grep起

  grep原先是ed下的一个应用程序,其名称来自于g/re/p(globally search a regular expression and print,以正规表示法进行全域查找以及打印),在ed下,输入g/re/p这个命令后,会将所有符合原先定义的字符串,以行为单位打印出来

 

二、grep用处

  grep是用来搜索文本或者搜索某些文件里面的行,这些行里面包括和给定的字符串或者单词相匹配的字符串或者单词。默认情况下,grep显示出匹配到的行。用grep搜索文本,找到里面匹配一个或者多个正则表达式的行,并且输出这些行。Grep被认为是UNIX和其他类UNIX操作系统中最有用的命令之一。

 

三、grep使用

  • grep [OPTIONS] PATTERN[FILE...]

  • grep[OPTIONS] PATTERN [FILE...] 中的PATTERN可以是一个字符长,也可以是一个正则表达式

 

PATTERN是一个字符串

grep常用选项:

--color
  •  搜索到"hi"字符串,显示为红色,auto表示自动的

  • ps:建议把grep用alias别名一下,这样的话,以后用grep搜索到的内容不用加color参数就会高亮显示,方法:alias grep='grep --color=auto'

  • 注意:后文的代码我在执行的时候是高亮显示的,但是由于这个博客编辑器的原因,没有办法高亮显示了,建议大家把代码自己执行一下,自己去分析结果,这样学习效果才会有。

[root@localhost bash]# grep --color=auto 'hi' b.txt
hi jerry
-v:反向选取,以下面为例,就是不包含"hi"字符串
[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.

[root@localhost bash]# grep -v 'hi' b.txt
hello world
my name is linux.
-o:仅显示匹配到的内容
[root@localhost bash]# grep 'hi' b.txt
hi jerry
[root@localhost bash]# grep -o 'hi' b.txt
hi
-n:在查出来的每个行的前面加上每行在文件中的行号
[root@localhost bash]# cat -n /etc/issue
     1    CentOS release 6.5 (Final)
     2    Kernel \r on an \m
     3    
     4    Mage Education Learning Services
     5    http://www.magedu.com
     6    
[root@localhost bash]# grep -n 'www' /etc/issue
5:http://www.magedu.com
-i:忽略字符大小写,以下面为例,加上-i之后,能匹配到"My"了
[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
My name is linux.

[root@localhost bash]# grep 'my' b.txt
my name is linux.
[root@localhost bash]# grep -i 'my' b.txt
my name is linux.
My name is linux.

 

-A #:把匹配到的行的后#行也打印出来,以下面为例,把匹配到的那一行的后两行也打印出来;
[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
what is your name?
Learn linux is fun.
Do you think so?

[root@localhost bash]# grep -A 2 'what' b.txt
what is your name?
Learn linux is fun.
Do you think so?
-B #:把匹配到的行的前#行业打印出来,以下面为例,把匹配到的那一行的前两行也打印出来;
[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
what is your name?
Learn linux is fun.
Do you think so?

[root@localhost bash]# grep -B 2 'what' b.txt
my name is linux.
Hello world
what is your name?
-C #:把匹配到的行的前#行和后#行也打印出来,如下所示,把匹配到那行的前后两行都打印出来;
[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
what is your name?
Learn linux is fun.
Do you think so?

[root@localhost bash]# grep -C 2 'what' b.txt
my name is linux.
Hello world
what is your name?
Learn linux is fun.
Do you think so?

 

3.2PATTERN是一个正则表达式:

 尽管直接使用最简单直接的pattern字串可以完成一些重要的任务,但是grep命令的真正的威力在于它可以使用正则表达式来完成复杂的模式字串的匹配。

3.2.1 什么是正则表达式?

正则表达式:

正则表达式又称正规表达式、正规表示法、正规表示式、规则表达式、常规表达式(英文:Regular Expression—>这里正好和grep的英文名对应,grep就是搜索正规表达式并且打印输出),在代码中常常简写为regex,regexp或RE,计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。许多程序设计语言都支持利用正则表达式进行字符串操作。例如,在Perl中就内建了一个功能强大的正则表达式引擎。正则表达式这个概念最初是由UNIX中的工具软件(例如sed和grep)普及开的。正则表达式通常缩写成”regex”,单数有regexp、regex,复数有regexps、regexes、regexen。

正则表达式历史:

最初的正则表达式出现于理论计算机科学的自动控制理论和形式化语言理论中。在这些领域中有对计算(自动控制)的模型和对形式化语言描述与分类的研究。 1940年,WarrenMcCulloch与Walter Pitts将神经系统中的神经元描述成小而简单的自动控制元。 1950年代,数学家斯蒂芬·科尔·克莱尼利用称之为“正则集合”的数学符号来描述此模型。肯·汤普逊将此符号系统引入编辑器QED,然后是Unix上的编辑器ed,并最终引入grep自此,正则表达式被广泛地使用于各种Unix或者类似Unix的工具,例如Perl。

正则表达式两类
grepPATTERN中分两类正则表达式:
  •   基本正则表达式:

  •   扩展正则表达式

 

Grep命令中使用的是基本的正则表达式,如果想使用更高级也就是扩展正则表达式需要指定选项-E,相当于egrep命令。

基本正则表达式:
包括四种类型的模式匹配规则
字符匹配:
  •  .:点号是用来匹配任意单个字符
  • 如下所示:"t...k"是匹配"t"和"k"之间有3个字符的字符串

[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
what is your name?
Learn linux is fun.
Do you think so?

[root@localhost bash]# grep 't...k' b.txt
Do you think so?
  • []:匹配指定集合中的任意单个字符,注意是单个字符

  • [[:digit:]] 或者 [0-9] -->匹配0到9之间的单个数字

  • 如下:查找b.txt中含有数字的行

[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
what is your name?
Learn linux is fun.
Do you think so?
10 you think so?
[root@localhost bash]# grep '[[:digit:]]' b.txt
10 you think so?


[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
what is your name?
Learn linux is fun.
Do you think so?
10 you think so?
[root@localhost bash]# grep '[0-9]' b.txt
10 you think so?

 

  • [[:lower:]]  [a-z]  -->匹配单个小写字母

  • 如下:查找b_test.txt中含有小写字母的行

[root@localhost bash]# cat b_test.txt
HI ,WHAT IS YOUR NAME?
MY NAME IS JERRY
HOW OLD ARE YOU?
I am 22.
[root@localhost bash]# grep '[[:lower:]]' b_test.txt
I am 22.

[root@localhost bash]# cat b_test.txt
HI ,WHAT IS YOUR NAME?
MY NAME IS JERRY
HOW OLD ARE YOU?
I am 22.
[root@localhost bash]# grep '[a-z]' b_test.txt

 

  • [[:upper:]] [A-Z]  -->匹配单个大写字母

  • 如下:查找b.txt中含有大写字母的行

[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
what is your name?
Learn linux is fun.
Do you think so?
10 you think so?
[root@localhost bash]# grep '[[:upper:]]' b.txt
Hello world
Learn linux is fun.
Do you think so?

[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
what is your name?
Learn linux is fun.
Do you think so?
10 you think so?
[root@localhost bash]# grep '[A-Z]' b.txt
Hello world
Learn linux is fun.
Do you think so?

 

  • [[:alpha:]] [a-zA-Z] -->匹配单个大写字母或者单个小写字母

  • 如下:查找b.txt中不含大小写字母的行

[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
what is your name?
Learn linux is fun.
Do you think so?
10 you think so?
100
[root@localhost bash]# grep -v '[[:alpha:]]' b.txt
100

[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
what is your name?
Learn linux is fun.
Do you think so?
10 you think so?
100
[root@localhost bash]# grep -v '[a-zA-Z]' b.txt
100

 

  • [[:alnum:]] [0-9a-zA-Z] -->匹配单个0到9之间的数字或者单个小写字母或者单个大写字母

  • 如下:查找含有数字或者小写字母或者大写字母的行;

[root@localhost bash]# cat c.txt
how old are you ?
i am 22
*****
[root@localhost bash]# grep '[[:alnum:]]' c.txt
how old are you ?
i am 22

[root@localhost bash]# cat c.txt
how old are you ?
i am 22
*****
[root@localhost bash]# grep '[0-9a-zA-Z]' c.txt
how old are you ?
i am 22

 

  • [[:space:]] -->匹配空白字符包括空格、tab

  •  如下:查找含有空格的行

[root@localhost bash]# cat c.txt
how old are you ?
i am 22
*****
youyouyouyou

[root@localhost bash]# grep '[[:space:]]' c.txt
how old are you ?
i am 22

 

  • [[:punct:]]-->匹配单个除了数字、大小写字母的符号

  • 如下:查找含有除了数字、大小写字母的行

[root@localhost bash]# cat c.txt
how old are you ?
i am 22
*****
youyouyouyou
my name is jerry,and what is your name?

[root@localhost bash]# grep '[[:punct:]]' c.txt
how old are you ?
*****
my name is jerry,and what is your name?

 

  • [^]:匹配指定集合外的任意单个字符

  • 如下:查找含有非数字的行

[root@localhost bash]# grep '[^0-9]' b.txt
hello world
hi jerry
my name is linux.
Hello world
what is your name?
Learn linux is fun.
Do you think so?
10 you think so?
[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
what is your name?
Learn linux is fun.
Do you think so?
10 you think so?
100


 

  匹配次数:
  • 对其前面紧邻字符所能出现的次数做出限定

  • *:匹配其前面的字符任意次,0次1次多次都行;

  • 如下:可以自行理解下面的过程

[root@localhost bash]# cat d.txt
xy
xxy
xxxy
xxxxy
y
nxy
[root@localhost bash]# grep 'x*y' d.txt
xy
xxy
xxxy
xxxxy
y
nxy
[root@localhost bash]# grep 'xx*y' d.txt
xy
xxy
xxxy
xxxxy
nxy
[root@localhost bash]# grep 'xxx*y' d.txt
xxy
xxxy
xxxxy


  • \?: 匹配其前面的字符0次或者1次,也就是说没有可以,有的话只能出现一次;

  • 如下:可以自行理解下面的过程

[root@localhost bash]# cat d.txt
xy
xxy
xxxy
xxxxy
y
nxy
[root@localhost bash]# grep 'x\?y' d.txt
xy
xxy
xxxy
xxxxy
y
nxy
[root@localhost bash]# grep 'xx\?y' d.txt
xy
xxy
xxxy
xxxxy
nxy


  • \+: 匹配其前面的字符至少一次;

  •  如下:可以自行理解下面的过程

[root@localhost bash]# cat d.txt
xy
xxy
xxxy
xxxxy
y
nxy
[root@localhost bash]# grep 'x\+y' d.txt
xy
xxy
xxxy
xxxxy
nxy
[root@localhost bash]# grep 'xx\+y' d.txt
xxy
xxxy
xxxxy
[root@localhost bash]# grep 'xxx\+y' d.txt
xxxy
xxxxy

 

  • \{m\}: 匹配其前面的字符m次;

  • 如下:可以自行理解下面的过程

[root@localhost bash]# cat d.txt
xy
xxy
xxxy
xxxxy
y
nxy
[root@localhost bash]# grep 'x\{2\}y' d.txt
xxy
xxxy
xxxxy
[root@localhost bash]# grep 'x\{1\}y' d.txt
xy
xxy
xxxy
xxxxy
nxy
[root@localhost bash]# grep 'x\{3\}y' d.txt
xxxy
xxxxy


  • \{m,n\}: 匹配其前面的字符至少m次,最多n次;

  •  如下:可以自行理解下面的过程

[root@localhost bash]# cat d.txt
xy
xxy
xxxy
xxxxy
y
nxy
[root@localhost bash]# grep 'x\{1,2\}y' d.txt
xy
xxy
xxxy
xxxxy
nxy
[root@localhost bash]# grep 'x\{2,4\}y' d.txt
xxy
xxxy
xxxxy
[root@localhost bash]# grep 'x\{3,5\}y' d.txt
xxxy
xxxxy

 

  • \{m,\}: 匹配其前面的字符至少m次,大于m次无限制;

  • 如下:可以自行理解下面的过程

[root@localhost bash]# cat d.txt
xy
xxy
xxxy
xxxxy
y
nxy
[root@localhost bash]# grep 'x\{2,\}y' d.txt
xxy
xxxy
xxxxy
[root@localhost bash]# grep 'x\{3,\}y' d.txt
xxxy
xxxxy
[root@localhost bash]# grep 'x\{4,\}y' d.txt
xxxxy
[root@localhost bash]# grep 'x\{5,\}y' d.txt
[root@localhost bash]#


  • .*: 匹配任意长度的字符

  • 如下:查找/etc/passwd文件中包含以"r"开头以"t"结尾的字符串的行

[root@localhost bash]# grep 'r.*t' /etc/passwd
root:x:0:0:Administrator,1456,741,963:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
rtkit:x:499:497:RealtimeKit:/proc:/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
saslauth:x:498:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
user6:x:4009:4009::/tmp/user6:/bin/bash
user8:x:4010:4010::/home/user8:/bin/tcsh
user21:x:4012:4012::/tmp/user21:/bin/bash
gentoo:x:4021:4021::/users/gentoo:/bin/bash
centos:x:4022:4022::/users/centos:/bin/bash
 位置锚定:

 

  • ^: 锚定行首

  • 如下:查找/etc/passwd文件中以"r"开头的行

[root@localhost bash]# grep '^r' /etc/passwd
root:x:0:0:Administrator,1456,741,963:/root:/bin/bash
rtkit:x:499:497:RealtimeKit:/proc:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/cache/rpcbind:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin

 

  • $: 锚定行尾

  •  如下:查找/etc/passwd文件中以nologin结尾的行

[root@localhost bash]# grep 'nologin$' /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
rtkit:x:499:497:RealtimeKit:/proc:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/cache/rpcbind:/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
haldaemon:x:68:68:HAL daemon:/:/sbin/nologin
gdm:x:42:42::/var/lib/gdm:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
apache:x:48:48:Apache:/var/www:/sbin/nologin
saslauth:x:498:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
pulse:x:497:496:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
pgsql:x:495:492::/home/pgsql:/sbin/nologin
nologin:x:4017:4017::/home/nologin:/sbin/nologin
mysql:x:4020:491::/home/mysql:/sbin/nologin
test:x:4023:4023::/home/test:/sbin/nologin

 

  • ^$: 锚定空白行

  • 如下:查找/etc/issue文件中的空白行

[root@localhost bash]# cat -n /etc/issue
     1    CentOS release 6.5 (Final)
     2    Kernel \r on an \m
     3    
     4    Mage Education Learning Services
     5    http://www.magedu.com
     6    
[root@localhost bash]# grep -n '^$' /etc/issue
3:
6:

 

  • \<或者\b: 锚定词首

  • 如下:自行理解下面的过程

[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
root is 
what is your name?
Learn linux is fun.
Do you think so?
hasrootis
10 you think so?
100
hy root hehe
[root@localhost bash]# grep 'root' b.txt
root is 
hasrootis
hy root hehe
[root@localhost bash]# grep '\<root' b.txt
root is 
hy root hehe

 

  • \>或者\b: 锚定词尾

  • 如下:自行理解分析下面的执行过程

[root@localhost bash]# vim b.txt
[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
root is 
what is your name?
Learn linux is fun.
Do you think so?
hasrootis
10 you think so?
100
hy roothehe
[root@localhost bash]# grep 'root' b.txt
root is 
hasrootis
hy roothehe
[root@localhost bash]# grep 'root\>' b.txt
root is


  • \<\>:锚定单词

  • 如下:自行理解下面过程

[root@localhost bash]# cat b.txt
hello world
yourroot is hhi
hi jerry
my name is linux.
Hello world
root is 
what is your name?
Learn linux is fun.
Do you think so?
hasrootis
10 you think so?
100
hy roothehe
[root@localhost bash]# grep 'root' b.txt
yourroot is hhi
root is 
hasrootis
hy roothehe
[root@localhost bash]# grep '\<root\>' b.txt
root is


  • \|:或

  • 如下:搜索god或者good

[root@localhost bash]# cat n.tx
hi god ll
what good uuu
lsd oweur
oweu9r oweur 
hh ngodl ii
sdf sdf or
af ewgoode ee
[root@localhost bash]# grep 'god\|good' n.tx
hi god ll
what good uuu
hh ngodl ii
af ewgoode ee


  • \(\):分组

  • 如下:搜索n.tx中的"good"或者"gold"

[root@localhost bash]# cat n.tx
hi god ll
what good uuu
lsd oweur
oweu9r oweur 
i love gold
hh ngodl ii
sdf sdf or
af ewgoode ee
good is what?

[root@localhost bash]# grep 'go\(o\|l\)d' n.tx
what good uuu
i love gold
af ewgoode ee
good is what?
  后向引用:
  •   如果在模式中使用\(\)实现了分组,在文本检查中,如果\(\)模式匹配到了某个内容,此内容后面的模式可以被引用;用\1引用第一个\(里面的内容,用\2应用第二个\(里面的内容,一次类推\3、\4 …….

  • 如下:查找m.txt中后面的名词是前面动词加r的行

[root@localhost bash]# cat m.txt 
I like a liker
I love a lover
I like a lover
I love a liker
[root@localhost bash]# grep 'l..e.*l..er' m.txt 
I like a liker
I love a lover
I like a lover
I love a liker
[root@localhost bash]# grep '\(l..e\).*\1' m.txt 
I like a liker
I love a lover


扩展正则表达式 

见名思义,可知是扩展的正则表达式,比基本正则表达式所支持的功能更多,在上面的基本正则表达式中大家可能最常见的就是"\"这个符号,这个符号就是转义字符,除了单词锚定的这个"\<\>"符号在扩展正则表达式不变,其余的如果想用在扩展的正则表达式上的话,去掉"\"就行了,其余的都不变,由于时间问题我在这里就不废话了,大家自己练习就行。