grep详解

来源:互联网 发布:西北大学网络教育 编辑:程序博客网 时间:2024/06/06 04:21

grep是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。

grep家族包括,grep,egrep和fgrep

原理

说说grep的原理吧?

在给出文件列表或标准输入后,grep会对匹配的一个或多个表达式的文本进行搜索,并只输出匹配

(或者不匹配)的行或文本

其实,说白了,grep的过程和sed的寻址过程差不了多。

参照sed处理过程,我们总结下grep的处理过程

  1. 将一行文本读取模式空间

  2. 根据指定的正则,搜索该行文本,看是否有匹配的内容

  3. 如果,整行一次匹配都没有,该行不做后续的处理了,删除该行并读入下一行

  4. 如果匹配成功,则打印该行,并读入下一行。

这么看起来,grep其实就是一个简化版的sed,对于的匹配成功的行自动的打印出来,而sed中需要指定p命令来打印,否则整个文本都会被打印。 当然grep的option提供了很多的参数,也有着很多sed没有的功能。

OK,既然这样了,那grep就剩下两块内容了,一个是grep的参数,一个是正则寻址

说到正则,grep中使用正则和sed,awk有点区别,sed或awk中要用//圈起来。而grep中则不需要


语法格式

grep [option] pattern [file...]

grep [options] [-e pattern] -f []

grep -E 相当于egrep,grep -F相当于fgrep,grep -r 相当于rgrep

下面来看看grep的[options]吧

介绍[options]的过程中会弄点小例子,练习下元字符的及grep,egrep,fgrep的使用。

楼主把自己认为可能会被经常用到的参数用颜色,mark一样

grep -V   这个可以看grep的版本

测试文本

John Daggett, 341 King Road, Plymouth MAAlice Ford, 22 East Broadway, Richmond VAOrville Thomas, 11345 Oak Bridge Road, Tulsa OKTerry Kalkas, 402 Lans Road, Beaver Falls PAEric Adams, 20 Post Road, Sudbury MAHubert Sims, 328A Brook Road, Roanoke VAAmy Wilde, 334 Bayshore Pkwy, Mountain View CASal Carpenter, 73 6th Street, Boston MAansible is ansiblesaltstcak is more powerful than (ansible),heheansibl are ansible

匹配器的选择

参数
描述
例子
-E
用ERE描述的匹配模式,和egrep的效果一样

grep -E '(MA|VA)$' list

egrep  '(MA|VA)$' list

-F
不识别正则,只识别字符串,速度比grep快。和fgrep的效果一样。

grep -F 'Sudbury' list

egrep 'Sudbury' list

-G
用BRE描述的匹配模式,grep默认就是这种模式

grep  -G'^A..[a-z]\{2\}'  list

grep  '^A..[a-z]\{2\}'  list

-P
用Perl风格的正则描述的匹配模式
不会Perl,就不举例子了

匹配控制

参数
描述
例子
-e PATTERN

声明这个参数后面的是正则,感觉用处不大啊

grep -e 'Po \{0,1\}'  list

grep 'Po \{0,1\}'  list

-f FILE
后面跟着文件,文件里写的是正则
grep  -f  list.grep   list-i
忽略大小写的区别,这个即作用在正则里面,也作用在输入文件的文本行里面
egrep  -i 'roa(d|noke)[ ,]+'  list-v
打印未匹配的行
fgrep 'Adams' list-w

文本行中要包含,完整的单词。。。比如

正则是'road',road是可以匹配的,但是roads则无法匹配

grep -w -E 'Road?' list
-x
匹配一整行的内容,也就是说,匹配模式表达的内容必须是一整行,而不是行中的某个关键词
grep -x 'John Daggett, 341 King Road, Plymouth MA' list
-y
也是忽略大小写,-i没出来之前用的就是它
grep  -y 'roAd'  list


输出控制

参数
描述
例子
-c --count
输出匹配到的次数(注意一行最多被匹配一次)
egrep -c '[0-9?] ?[A-Z]?[a-z]+'  list--color[=WHEN]

就是我们''正则表示的文本,会被加上颜色打印出来,WHEN可以是always,auto,never等参数。。

当然也可以不加WHEN,直接用--color就OK了

egrep --color '[AH]'  list-L
抑制输出文件名,注意这里的输出是匹配的文件名,而不是文本行
egrep -L '^[A-Z]?[a-z]{4}[^a-z0-9]' list-l
正常输出,输出的为匹配的文件名,而不是文本行
egrep -l '^[A-Z]?[a-z]{4}[-a-z?0-9]' list 
-m NUM
匹配成功NUM个文本行后,则停止匹配
egrep -m 2 '[A-Z]?[a-z]{7} ?.A$' list 
-o
只打印匹配的文本段,而不是打印整行
egrep -o '^(ansible) ?is ?\1'   list-q
终端不打印任何东西,一旦匹配成功,则以0状态码退出
egrep -q ' +\(ansible\)[ ,]'  list-s
抑制错误信息的输出,比如当文件不存在或者不可访问的时候。类似于shell中的定向到/dev/null.   但是当发生错误的时候,虽然不打印但退出码不为0,通常为2
egrep  -s '\<[0-9]+ ?[A-Z]?[a-z]{2}\>'  list

输出行前缀控制

参数
描述
例子
-b
打印匹配行字节数,每输入一行,大小累加
egrep -b '^ansible? (is|are)'  list-H
匹配行的前面,加上文件名
egrep -i -H '^an[-a-z^*]Ible' list-h
匹配行前面不加文件名,默认就是这样的
egrep -h '[0-9]{4,}' list--lable=LABLE

不会用

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


-n
打印匹配行的行号
grep -n '^$' list-T
没研究

-u
没研究

-Z
没研究

内容控制


参数
描述
例子
-A NUM
这三个东西差不多其实,man手册里解释-A是在匹配内容后,-B是在匹配内容前打印NUM行,多个文件匹配内容之间加一行包含--的行。。。。。。楼主测了下,这三个东西在处理多个文件的时候,效果差不多。。。。都是每个文件匹配内容直接多个了--的行
grep -A 3 ‘.*’ list list
-B NUM
-C NUM

文件及目录选项

参数
描述
例子
-a
把binary文件当做text文件处理
egrep -a -r '(while|for|do)' /sbin/*
--binary-files=TYPE
TYPE默认为binary,会处理binary文件。当TYPE设置为without-match的时候,跳过binary文件,当TYPE为text的时候,binary文件被当作text文件处理
egrep -r --binary-files=without-match '[ #?include<?' /sbin/*
-D ACTION
输入文件为设备,管道或者socketd的时候。ACTION默认为read,但是有些设备不可读,所以就容易出错。。。这时候,我们可以设置ACTION为skip,就可以跳过这些文件
egrep -r -D skip 'cards?' /dev/*
-d ACTION

输入文件为文件夹的时候。ACTION默认为read,可想而知,文件夹咋read呢?

ACTION可以设置为skip跳过,或者设置为recurse,读取文件夹下的内容

grep -d recurse 'ERROR' /var/log/
--exclude=GLOB
排除GLOB描述的文件,包含文件和文件夹,可以用*, ?, and [...]等shell符号,也可以用\,转移这些符号egrep -r --exclude=Apache2* 'Jun 1[4-8] ([0-9]:){3}' /var/log/
--exculde-from=FILE
排除FILE描述的文件名
egrep -r --exculd-from=mysq?* '(WARN|ERROR)' /var/log/
--exclude-dir=DIR
排除DIR描述的文件夹,
egrep -r --excild-dir=apt 'salt-master' /var/log/
-I
忽略二进制文件,因为二进制文件一般来说不存在我们需要的匹配结果
egrep -I  '\\\.' /sbin/
--include=GLOB
读取GLOB描述的文件,可以用*, ?, and [...]等shell符号,也可以用\,转移这些符号egrep -r --include=error.log 'error' /var/log/
-R,-r
递归读取文件夹下所有的文件
grep 'ERROR' /var/log/*



其它选项

参数
描述
例子
--line-buggered
没研究

--mmap
没研究

-U
没研究

-z
没研究

退出状态

匹配成功,退出状态码为0,匹配失败退出状态码为1,匹配出现错误退出码为2


OK,总结完了sed,awk,grep。说到底最重要的还是正则表达式啊,有空多看看《精通正则表达式》这本书吧

原创粉丝点击