Grep简介
全名:Global search Regular expression and Print out the line.
功能:文本搜索工具,根据用户指定的文本模式(搜索条件)对目标文件进行逐行搜索,显示能匹配到的行。
Linux的三大文本处理工具之一,可以说学好grep命令无疑是重要的,可以说学好grep也是不容易的,因为grep里面要用到最烦人的正则表达式。
grep语法格式
grep [option]... ‘PATTERN‘ FILE...
[option]:表示可以跟选项,中括号表示可以省略,…表示可以跟多个选项
PATTERN:这个可以跟上模式,也就是可以使用正则表达式来进行匹配搜索,正则表达式下面会细说。
FILE…:表示后面可以跟上多个进行文本搜索的文件
Eg:查找/etc/passwd这个文件里面包含root字眼的行,从下图可以看出,打印出来的行,每一行的内容都包含有root字眼,这就是grep的作用
W注意点:模式当中一但包含元字符一定要用‘‘或""号引起来,单双引号都可以、只不过如果其中出现了变量、并且我们希望做变量替换的话那就要使用""双引号了、否则可以不加区分的使用。
常用选项[option]
--color=auto:用颜色显示出匹配的内容
可以看到,被匹配的内容都通过颜色高亮出来,这样很有助于我们去检查给予的匹配条件有没有符合我们的要求。所以平时都要带上这个选项,但是又不想每次都输入,就可以在~/.bashrc里面加入alias grep=‘grep --color=auto‘就可以了。
-v: 反向选取:就是表示取反,把没有匹配到的行显示出来
-i:匹配的时候,对于匹配的条件忽略字符大小写
正则表达式的简介
如果grep命令只是可以匹配给定的具体字符的话,那估计grep就没有这么大的魔力了,当然也不敢号称是三大文本处理工具之一了。想用好grep,就要学会怎么样让grep去进行模式(就是正则表达式)匹配,这就脱不开正则表达式,虽然正则表达式很烦人,但是学好了,作用是非常大。
概念:是一类字符所书写的模式,其中许多字符不表示其字面意义,而是表达控制或通配等功能,这类字符就是所谓的元字符。
混淆点:正则表达式不是由bash shell环境去解释的,而是通过正则表达式引擎来解释,也就是说命令自己要去实现和解释正则表达式。
正则表达式可以分为两种:基本正则表达式和扩展正则表达式,接下来就会细说这两者。
基本正则表达式
正则表达式不外乎是一堆元字符组成的模式,对于基本正则表达式,可以把元字符分为四个方面
1、 字符匹配:用来匹配相应的字符的,比如是数字还是字母一类的。。。
. 匹配任意单个字符
Eg: grep "r..t" /etc/passwd 表示匹配以r字母为首,中间出现任意两个字符,然后紧跟t字母的子串
[] 匹配指定范围内的任意单个字符
[ade] 这样就表示,可以匹配a或者d或者e
对于中括号,这里还有一些特殊含义的字符
[0-9], [[:digit:]] 数字
[a-z], [[:lower:]] 小写字母
[A-Z], [[:upper:]] 大写字母
[[:space:]] 空格
[[:punct:]] 标点符号
[[:alpha:]] 字母
[[:alnum:]] 字母+数字
Eg:grep “[0-9][0-9]” /etc/fstab 表示找两个数字一起的子串
[^] 表示取反,也就是非
2、 次数匹配元字符:用于实现指定其前面的字符所能够出现的次数
*: 任意长度,它前面的字符可以出现任意次
例如:x*y 可以用来匹配xxy, xyy, y,
\?: 0次或1次,它前面的字符是可有可无的
例如:x\?y 可以用来匹配xy, y, ay
\{m\}: m次,它前的字符要出现m次
例如:x\{2\}y 可以用来匹配xy, xxy, y, xxxxy, xyy
\{m,n\}: 至少m次,至多n次
例如:x\{2,5\}y 可以用来匹配xy, y, xxy
\{m,\}:至少m次
\{0,n\}: 至多n次
\+:至少1次
. *:任意长度的任意字符
Eg:grep “[0-9]\{1,3\}” /etc/fstab 表示匹配数字至少出现一次,至多出现三次的子串
3、 位置锚定:
^: 行首锚定;
写在模式最左侧,表示必须从行首开始匹配
$: 行尾锚定:
写在模式最右侧,表示必须以这个结尾
\<:>
出现于单词左侧,表示必须从词首开始匹配
\>: 词尾锚定:
出现于单词右侧,表示必须以这个作为单词结束
\b:可以用来代替\
Eg:查找/etc/fstab中以#开头的内容
4、 分组:
\(\) 例如:\(ab\)*
\(\)还可以用来引用:分组中的模式匹配到的内容,可由正则表达式引擎记忆在内存中,之后可被引用
\#: 引用第n个括号所匹配到的内容,而非模式本身
Eg:从文本中匹配同一行中有连续两个相同子串的内容
扩展正则表达式简介
Grep如果要使用扩展正则表达式的话,要带上-E的选项,或者使用egrep命令也可以。
扩展正则表达其实和基础正则表达式一样,但是扩展正则表达的好处就是及少使用转义的符号,不会被一大堆的转义符号搞得晕头转向的。
使用扩展正则表达式,还多了一个功能,就是可以使用具备或功能的元字符(|),它的功能很好用,很多情况就是有了或功能,正则表达式的模式会变得比较短小。
扩展正则表达式
跟基本正则表达式一样,也总共分四类
1、 字符匹配
. 匹配任意单个字符
[] 匹配指定范围内的任意单个字符
[ade] 这样就表示,可以匹配a或者d或者e
对于中括号,这里还有一些特殊含义的字符
[0-9], [[:digit:]] 数字
[a-z], [[:lower:]] 小写字母
[A-Z], [[:upper:]] 大写字母
[[:space:]] 空格
[[:punct:]] 标点符号
[[:alpha:]] 字母
[[:alnum:]] 字母+数字
[^] 表示取反,也就是非
2、 次数匹配元字符
*:任意次
?: 0次或1次
+: 至少1次;
{m}: 精确匹配m次
{m,n}: 至少m次,至多n次
{m,}:至少出现m次
{0,n}:至多出现n次
3、 位置锚定
^:行首锚定
$:行尾锚定
\
\>, \b:词尾锚定
4、 分组
()
引用:\1, \2, \3
5、 或者
a|b: a或者b
eg:取/etc/passwd文件里面带有root或者dump的内容
Fgrep的使用
fgrep:它不支持正则表达式,你找想什么具体的字符就写什么具体的字符,所以它的查找速度也是最快的;
例:fgrep "/bin/bash" /etc/passwd
练习测试
这里直接给出题目和结果,通过练习可以让我们更好的掌握知识点
基本正则表达式练习:
1、显示/proc/meminfo文件中以大写或小写S开头的行;
# grep -i ‘^s‘ /proc/meminfo
# grep ‘^[Ss]‘ /proc/meminfo
# grep -E ‘^(S|s)‘ /proc/meminfo
2、显示/etc/passwd文件中其默认shell为非/sbin/nologin的用户;
# grep -v "/sbin/nologin$" /etc/passwd | cut -d: -f1
3、显示/etc/passwd文件中其默认shell为/bin/bash的用户;
进一步:仅显示上述结果中其ID号最大的用户;
# grep "/bin/bash$" /etc/passwd | sort -t: -k3 -n | tail -1 | cut -d: -f1
4、找出/etc/passwd文件中的一位数或两位数;
# grep "\" /etc/passwd
# grep "\" /etc/passwd
5、显示/boot/grub/grub.conf中以至少一个空白字符开头的行;
# grep "^[[:space:]]\{1,\}" /boot/grub/grub.conf
6、显示/etc/rc.d/rc.sysinit文件中,以#开头,后面跟至少一个空白字符,而后又有至少一个非空白字符的行;
# grep "^#[[:space:]]\{1,\}[^[:space:]]\{1,\}" /etc/rc.d/rc.sysinit
7、找出netstat -tan命令执行结果中以‘LISTEN‘结尾的行;
# netstat -tan | grep "LISTEN[[:space:]]*$"
8、添加用户bash, testbash, basher, nologin(SHELL为/sbin/nologin),而找出当前系统上其用户名和默认shell相同的用户;
# grep "^\([[:alnum:]]\{1,\}\):.*\1$" /etc/passwd
9、扩展题:新建一个文本文件,假设有如下内容:
He like his lover.
He love his lover.
He like his liker.
He love his liker.
找出其中最后一个单词是由此前某单词加r构成的行。
\(l..e\).*\1r
扩展表达式练习
10、显示当前系统上root、fedora或user1用户的默认shell;
# grep -E "^(root|fedora|user1):" /etc/passwd | cut -d: -f7
11、找出/etc/rc.d/init.d/functions文件中某单词后跟一组小括号“()”行;
# grep -o -E "\\(\)" /etc/rc.d/init.d/functions
12、使用echo命令输出一个路径,而后使用grep取出其基名;
# echo "/etc/sysconfig/" | grep -o -E "[[:alnum:]]+/?"
# echo "/etc/sysconfig/" | grep -o -E "[^/]+/?$" | cut -d/ -f1
13、找出ifconfig命令结果中的1-255之间的数字;
# ifconfig | grep -o -E "\"
14、挑战题:写一个模式,能匹配合理的ipv4地址;
1.0.0.1-239.255.255.255
原文:http://leezc.blog.51cto.com/8650393/1437657