在马哥教育学习Linux第二周,这周又学习了一些Linux的基础知识,通过写这篇文章对自己的这周所学做一个简单的梳理和回顾。

     grep是一款Unix上的命令行工具,它最初设计开发用于Unix操作系统,但是如今几乎所有的类Unix(Unix-like)操作系统都在使用。grep是由Unix的创造者之一的Ken Thompson所编写,第一次出现在是version 4 Unix中 。 grep是英文 globally search a regular expression and print的缩写,它的作用从名字就能看出,使用正则表达式做全局搜索并打印出所有匹配行。grep和egrep、fgrep构成了grep家族,后两者是由AWK的联合创作者Al Aho在1975年编写。

     Linux作为一款类Unix系统,其使用的也是grep,不过Linux使用的应该是GNU grep,也是GNU版本的grep。

     在谈到如何使用grep之前我们的先学习下正则表达式。

基本正则表达式元字符

     1)字符匹配。

.

 匹配任意单个字符(换行符除外)

[]

匹配范围内的任意单个字符

[^]

匹配范围外的任意单个字符

     2)匹配次数:限制其前面的字符要出现的次数。

*

匹配前面的字符任意次(0次、1次或者多次),例如 .* 代表的就是任意长度任意字符

\+

匹配前面的字符至少一次

\?

匹配之前的字符0次或者一次

\{m\}

匹配之前的字符m次,m未非负整数,例x\{2\} 匹配x两次

\{m,n\}

匹配之前的字符至少出现m次,最多出现n次。m和n为非负整数。

     3)位置锚定:限制匹配到的字符在文本中出现的位置。grep搜索是贪婪模式的,只要字符串中有匹配到的字符就打印出来,所以加位置锚定更加精确查找。

^

行首锚定,用在模式的最左侧。例: ^a的意思是以a开头的行。

$

行尾锚定,用在模式的最右侧。例:a$的意思是以a结尾的行。^$表示空行。

\<或\b

单词词首锚定,用于单词模式的最左侧,限制要匹配的单词要以什么开头。

\>或\b

单词词尾锚定,用于单词模式的最右侧,限制要匹配的单词要以什么结尾。例:\<this\> 匹配this这个单词。

     4)分组与引用

          \(PATTERN\) :将此PATTERN匹配到的字符当做一个不可侵害的整体进行处理。分组括号中的模式匹配到的字符会被正则表达式引擎自动记录在内部的变量中,这些变量是\1、\2...,\1表示第一组括号中的pattern中匹配到字符串,同理\2表示第二组括号中匹配到的字符串。具体的说就是\n:模式中第几个左括号以及与之匹配的右括号之间的模式所匹配到的字符串;不是模式本身,而是匹配到的结果。

          后向引用:引用前面的括号中的模式所匹配的字符串。举例说明:

          test.txt文件中有两行字符串分别为:abtcd fbtce和dbtca rbdca。我要找出找出第一个字符串就可以使用".\(b.c\).*\1."精确的匹配出了。具体操作命令在本文后面给出。

    5)POSIX字符类

         为了在不同的国家的字符编码中保持一致, POSIX(The Portable Operating System Interface)增加了特殊的字符类,常见的有:

[[:alnum:]]

所有字母和数字

[[:alpha:]]

所有字母

[[:digit:]]

所有数字

[[:upper:]]

所有大写字母

[[:lower:]]

所有小写的字母

[[:space:]]

空白字符

[[:punct:]]

标点符号

       扩展正则表达式与基本正则的主要区别如下:

       

基本正则表达式
扩展正则表达式
\++
\??
\{m\}{m}
\{m,n\}{m,n}
\(PATTERN\){m,n}

另外,扩展正则表达式多了一个或者“|”的概念。

        介绍完了基本正则表达式,我们就可以来说说grep的具体用法了。前文已经对grep的来历和作用做了简单的介绍,现在我们来介绍下grep的基本用法。

    命令的基本格式:

        grep [OPTIONS] PATTERN [FILE...]
        grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]

    常用命令选项:

       -i, --ignore-case:匹配时忽略大小写

       -v, --invert-match:反向匹配,只显示不匹配的

       -e PATTERN, --regexp=PATTERN:使用多个正则表达式

       -o, --only-matching:只显示匹配到的文本本身

       -q, --quiet, --silent:常用于脚本中

       -f FILE, --file=FILE:从文件中读取正则表达式

       --color[=WHEN], --colour[=WHEN]:对匹配到文本着色后高亮显示

       -E, --extended-regexp:使用扩展正则表达式匹配,相当于egrep

grep常用选项练习:

        在/tmp/目录下有个greptest.txt文件,其内容如下;

[root@localhost ~]# cat /tmp/greptest.txt 
This is first
how are you
How old are you 
fine,thanks
what,so what
What is you name
[root@localhost ~]#

        1、匹配文件中包含字符“you”的行

[root@localhost ~]# grep "you" /tmp/greptest.txt 
how are you
How old are you 
What is you name
[root@localhost ~]#

      2、匹配文件中包含字符“you”的行,且只输出匹配的行。

[root@localhost ~]# grep -o "you" /tmp/greptest.txt 
you
you
you
[root@localhost ~]#

       3、匹配文件中不包含字符“you”的行

[root@localhost ~]# grep -v "you" /tmp/greptest.txt 
This is first
fine,thanks
what,so what
[root@localhost ~]#

        4、匹配文件中包含字符“what”的行且不区分大小写

[root@localhost ~]# grep -i "what" /tmp/greptest.txt
what,so what
What is you name
[root@localhost ~]#

        5、匹配文件中包含字符“fine”的行和下一行

[root@localhost ~]# grep -A 1   "fine" /tmp/greptest.txt
fine,thanks
what,so what
[root@localhost ~]#

        6、匹配文件中包含字符“fine”的行和上一行

[root@localhost ~]# grep -B  1   "fine" /tmp/greptest.txt
How old are you 
fine,thanks
[root@localhost ~]#

        7、匹配文件中包含字符“fine”的行和上下各一行

[root@localhost ~]# grep -C  1   "fine" /tmp/greptest.txt
How old are you 
fine,thanks
what,so what
[root@localhost ~]#

        8、使用包含正则表达式的文件进行文本搜索

[root@localhost ~]# cat /tmp/grep
^f.*s$
[root@localhost ~]# grep -f /tmp/grep /tmp/greptest.txt 
fine,thanks
[root@localhost ~]#

         9、多个正则表达式搜索文本

[root@localhost ~]# grep -e  "^H.*u" -e  "^f.*s$"  /tmp/greptest.txt 
How old are you 
fine,thanks
[root@localhost ~]#

grep经典练习:

    在/tmp目录下有一个文件greptest1.txt,其内容如下:

[root@localhost ~]# cat /tmp/greptest1.txt
He like his liker
He love his lover
138074082711
She love her lover
jie231@sina.cn
She like her lover
18618203761
12
234
19209783900
1.0.0.254
1.0.0.255
255
256
1.2.3.4
223.255.255.254
224.255.255.252
2.255.255.255
1329873909
5678967@qq.com
12589098379
15608764083
ken_tom@netcom.org
jerry#li@baidu.net
li@souhu.net
13690876890

15820974619
[root@localhost ~]#

        1、分组与引用练习,搜索同时包含love和lover的文本

[root@localhost ~]# grep -E ".+(l.v.).+\1r" /tmp/greptest1.txt
He love his lover
She love her lover
[root@localhost ~]#

        2、数字查找练习,匹配1-255的数字

[root@localhost ~]# grep -E "^([1-9]|[1-9][1-9]|1[1-9][1-9]|2[1-4][1-9]|25[1-5])\$"  /tmp/greptest1.txt 
12
234
255
[root@localhost ~]#

        3、ip地址查找练习,匹配ABC类IP地址即 1.0.0.1---223.255.255.254

[root@localhost ~]# grep -E "\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-1][0-9]|22[0-3])\.(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){2}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4])\>" /tmp/greptest1.txt
1.0.0.254
1.2.3.4
223.255.255.254
[root@localhost ~]#

        4、匹配Email地址:任意长度数字字母@任意长度数字字母.(com"org|net等等)

[root@localhost ~]# grep -E "^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$" /tmp/greptest1.txt 
jie231@sina.cn
5678967@qq.com
ken_tom@netcom.org
li@souhu.net
[root@localhost ~]#

        5、匹配手机号码:手机号码是1[3|4|5|8]后面接9位数字的

[root@localhost ~]# grep -E  "\<1[3|4|5|8][0-9]{9}\>" /tmp/greptest1.txt 
18618203761
15608764083
13690876890
15820974619
[root@localhost ~]#