您的位置:首页 > 其它

论grep与正则表达式不得不说的秘密

2013-07-17 23:00 183 查看
这段时间完整性的学习了一下grep工具,今天拿来和大家分享一下:
说道grep命令,就不得不提一下正则表达式了。那什么是正则表达式呢,恩,这个问题问的很有技术含量,你要是不问,我还真不知道这篇博客怎么写呢。
什么是grep(Globalsearch Regular Exmpression and Printing):
应该先明白一个概念,grep是一种工具,一个强大的文本搜索工具。它使用正则表达式搜索文本,将文件输出。所有呢,大家应该能够明白。正则表达式才是整个grep中的精华。就像鸡汤一样,正则表达式是里面的鸡肉,而grep则是里面的汤。
grep家族有三个成员,分别是grep,egrep,fgrep.
什么是正则表达式:
正则表达式就是对字符串的一种组合描述。用一些事先定义好的字符与字符的集合,来表达对电脑的命令。
好吧,其实呢,这句话绕的我都晕了。咱们还是打个比喻吧。比如说一个很多内容的文本,里面有几千个英语单词,看的我眼花缭乱的。但是呢,老板要我从几千个单词中找到以r开头,以t结尾的所有单词(不要问我老板为什么提这个问题,就当吃饱了玩你的吧)。好吧,那我们开始找吧,找啊找啊,找到了下班估计都找不完。那怎么办呢。很简单啊,问电脑。对电脑说:“我要找这个文本中以r开头,以t结尾的单词,给我列出来”。那电脑听你的话么。废话,当然不听了。它要是听懂了,还要我们管理员干嘛呢。但是呢,既然电脑是一种简单的智能电脑,我们说人话它听不懂了,说简单的电脑语它不就听懂了么。那什么是电脑语呢。电脑语其实就是可以理解的正则表达式语言,比如刚才说的问题,我们只要输入“grep ‘\<r.*t\>’ FILES"就行了。 是不是看的头都大了,‘.’‘*’‘\<’代表的都是什么呢,这个就是正则表达式,以正则表达式来代替原有的内容向电脑输入这个,让电脑输出你所要的语言。所以呢,正则表达式是重中之重。学好正则表达式,走遍linux。哈哈
好了,是不是迫不及待了,让我们先介绍一下正则表达式。什么,还有grep?哦,忘了,其实只要学好了正则表达式,基本上就把我们今天的内容学习完了。因为我们学习的就是:“grep+正则表达式+文件”。这个公式就是一个计算机能够听懂的话了,也是我们现在要讲的东西。
正则表达式分为基本正则表达式和扩展正则表达式,他们有什么区别呢。
grep:支持正则表达式;
egrep支持扩展正则表达式,
fgrep:不支持正则表达式元字符,所以搜索字符串较快。
刚才我们所举的例子中,‘.’‘*’‘\<’中分别来代表什么呢,下面一个一个的讲解:
先来个简单的,让大家看看grep的用法,
grep [options] 'pattern' FILE,而其中pattern就是正则表达式的模式。
比如说,我们要找一下/etc/passwd中关于“root”的字母,该怎么着呢。很简单的:
grep "root" /etc/passwd 就是这样。



是不是很神奇的样子,别神奇了,后面的东西才叫神奇呢。
我们先看一下基本正则表达式中字符所代表的含义吧。
1、 ^:锚定行首的符合条件的内容,用法格式“^pattern”;
这个呢,就是找到一个字符为开头的行,比如说,在/etc/passwd中以abr为开头的行:




2、 $:锚定行尾的符合条件的内容,用法格式“pattern$”;
这个更简单了,比如,找到在/etc/passwd中以bash结尾的行,记着,$是在尾部的。




3、 ^pattern$:锚定行首和行尾。
这个不就是以行首和行尾找的么,比如:找到以roo开头,sh结尾的行



4 、^$:空白行
空白行是什么意思,顾名思义,就是空白的行呗,让我们来看一下



看见了没,是不是什么都没有,没错,这个就是空白行
5、 .:匹配任意单个字符
这个是什么意思,任意单个字符就是任意的一个大小写字母或者数字等等一个字符,当然了,要记住,空白符也是一个字符。我们以下面这个例子为例:



6、 *:匹配紧挨在前面的字符任意次
这个比较有意思,我们用一个例子来讲解一下,简历一个文档:a ab aab acb abc b,然后我们让a*b,这是什么意思,就是b前面有任意个a,也包括0个,让我们看一下



看见了没,b也是一个被匹配的字符,因为b前面有0个a。
7、 .*:匹配任意长度的任意字符
这个其实就是‘.’‘*’这两个元字符的组合,举个例子:在 /etc/passwd中,匹配yir开头,以h结尾的行:



不知道大家发现了没,为什么第一行中我话的地方还有两个r呢,那岂不是第二个r和第三个r也能和后面的h匹配了没? 没错,观察的很仔细,因为这牵扯到了一个基本正则表达式的贪婪模式。什么是贪婪模式,就是尽可能长的去匹配符合模式的内容。
8、 []:匹配指定范围内的任意单个字符
这个也很有意思,在上一个元字符中我们已经看到过,“r.*h”,如果我们想让r后面加一个数字(别问我为什么),那我们怎么办呢。哈 ,聪明的你已经开始想到这个‘[]'了,它是怎么使用的呢,还是/etc/passwd文件中,匹配一个r开头,后面跟一个任意数字,后面再跟任意字符,以h结尾



简单吧。对了,对于这个命令,我匹配的user1..,user2..,user3..等这个是我自己建立的用户账户才能匹配到的,你要是想运行一下这个命令,最好也先建立者三个用户。
9、 [^]:匹配指定外的任意单个字符
这个大家应该都能够猜出来吧,比如说[^0-9],则表示除了0-9之外的任意字符。这个就不实验了,大家私下自己试一下哈。顺便给大家补充一下知识。在正则表达式中,可以用一下字符表示:

[a-z] [A-Z] [0-9]
[:lower:] a-z
[:upper:] A-Z
[:digit:] 0-9
[:alpha:] 所有的大小写字母 a-z A-Z
[:alnum:] 所有的大小写字母和数字
[:space:] 空白字符
[:punct:] 标点符号
多吧,但要注意一下,上面的[:lower:]等这几个字符只是单纯的表示范围内的字符,如果要用于匹配的话,如匹配第八个[]的命令中,[0-9]等同于[[:lower:]],所以大家千万要记住了。
10、 \?:匹配紧挨在其前的字符0次或1次
如果我想匹配一个ab,或者是b,只要求b前面有一个或没有a怎么办呢,让我们来看一下。假如有一个文件,里面是ab,aab,acb,b,我想匹配b的前面有一个或者0个a,怎么办?这个就用到‘\?’元字符了。那你说,应该有哪几个字符匹配呢?想好了没,想好了我们试试:



11、 \{m,n\}:匹配其前面的字符至少m次,至多n次
这个看起来就有点难度了,让我们来举个简单的例子:我们还以10中的文档为例子:
a与b之间,我要匹配b前面最少有1个a,最多有两个a,那怎么匹配呢?这个:a\{1,2\}b:



不知道你看的头晕了没,如果没晕的话再加把劲。如果我要精确匹配呢,比如b前面我就要匹配一个a,那怎么表示呢,其实也不难:
grep a\{1\}b files



12、 哈哈,回过头看看,你已经学会了很多正则表达式了,还剩下最后几个,马上就完了。
说个简单的,如果我想要锚定一个单词怎么办,这个就是要教你的:
\<:锚定词手,用法格式:\<pattern

\>:锚定词尾,用法格式:pattern\>
举个例子,我想要知道/etc/passwd中以单词r开头,以单词t结尾的匹配



发现了没,我诠的最后一行单词。是不是很郁闷,它并不是一个单词啊。对啊,所以说\<pattern\> 锚定单词本身,pattern不一定是单词,可能只是字母的组合。
13、 \(\):分组,用法格式: \(pattern)
这是最后一个元字符了,也是比较难懂的一个,也是最绕我的一个,按照我老师马哥的话来说,这个靠的是自己的逻辑思维。汗一个,难道我的逻辑不好么!!!
好了,我们还是举个例子,例子是最好懂的。编辑一个文本: ab, aab, abb, abab, ababab。我想要知道ab这个字符前面有最少有1个ab,最多有3个ab的字符匹配,怎么办呢:
试试新学的这个:\(ab\)\{1,3\},看懂了么,后面的\{1,3\}是最少匹配1次,最多3次,大家应该能够学而致用哦。



让我们再来看最后一个非常好玩的东西。
如果a.b(.表示任意字符).*(表示任意长度的任意字符)a.b,但是呢,我想要前后两个a.b中的.(任意字符)一模一样,这可怎么办啊。仔细想想:
看看这个怎么样:\(a.b\).*\1 ,后面的\1表示与前面的a.b一样。
让我出一道题考考你 : 编辑一个文本:

He like his liker
He love his liker
She love her lover
She like her lover
我想要文中的l..e与后面的l..e中间的..(两个任意字符)一样,怎么办
看看这个命令: \(l..e\).*\1r



呼呼,终于将基本正则表达式说完了,下面我们来说说grep的用法,当然了,学会了基本正则表达式,grep的用法就是so easy了。

-v:反向选取,只显示不符合模式的行
-o:只显示被模式匹配到的字串,而不是整个行;
-A #:显示匹配到的行时,顺带显示其后面的#个行 after
-B #:显示匹配到的行时,顺带显示其前面的#个行 before
-C #:显示匹配的行的前后#行
-i:不区分字符大小写
-E:使用扩展的正则表达式
剩下的大家在自己的虚拟机或者真机上面一下就行了,我们来实验一个 -o吧
首先是没有-o选项的



这个是有-o选项的



看见了没,它只显示被模式匹配到的字串,其余的都不显示。
终于写完了,第一次写博客,写的乱七八糟的。哈 ,希望大家不要介意啊。都是初学者,希望大家能够好好的交流一下啊 。



本文出自 “LINUX的运维” 博客,请务必保留此出处http://xiguatailang.blog.51cto.com/7579245/1251621
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: