grep与正则表达式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了grep与正则表达式相关的知识,希望对你有一定的参考价值。

一、grep简介
二、基本正则表达式
三、egrep扩展正则表达式
四、其他文本及查看工具{wc,cut,sort,uniq,diff,patch}
五、练习用例

一、grep简介

    文本处理工具:

Linux上文本处理三剑客:

grep:文本过滤工具(模式:pattern)

grep:基本正则表达式,-E扩展,-F

egrep:扩展正则表达式,-G基本,-F

fgrep:不支持正则表达式,

sed:stream editor,流 编辑器

awk:Linux上实现的为Gawk,GNU/awk,文本报告生成器(格式化文本)

正则表达式:Regular Expression,REGEXP

    由一类特殊字符及文本所编写的模式,其中有些字符不表示其字面意义,而是用于表示控制或通配的功能

    分两类:

        基本正则表达式:BRE /basic REGEXP

扩展正则表达式:ERE /expansion REGEXP

//二者的元字符不同


    grep:Global search REgular expression and print out the line

        作用:文本搜索工具,根据用户指定的“模式(过滤条件)”对目标文本逐行进行匹配检查,打印匹配到的行

模式:由正则表达式的元字符及文本字符所编写的过滤条件

逐行搜索:逐行显示

正则表达式引擎:grep 自带有一个

    sed和awk各自的正则表达式引擎是不一样的

    perl语言的正则表达式引擎非常强

grep用法

    grep [OPTIONS] PATTERN [FILE...]

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

        OPTIONS

--color=auto //自动添加颜色

-i ignorecase 忽略大小写

-o 仅仅显示匹配到的子串本身

-v 反向匹配invert-match

-E extended-regexp扩展的正则表达式

-G 基本的正则表达式

-w --word-regexp

-x --line-regexp

-c 匹配到的次数

-q,--quiet 静默模式,不输出任何信息 //echo $?查看是否匹配成功

-n 显示行号

-A# :after,后#行

-B#:before,前#行

-C#:context,前后几行


二、基本正则表达式

    基本正则表达式元字符

字符匹配:

    .  匹配任意单个字符

    [] 匹配指定范围内的任意单个字符

    [^] 匹配指定范围外的任意单个字符

    [[:digit:]],[[:lower:]],[[:upper:]],[[:alpha:]],[[:alpha:]],[[:punct:]],[[:space:]]

匹配次数:用于限定其前面字符出现的次数

    * 匹配前面的字符任意次,0,1,n次

     grep x*y //x可以没有,但是y必须有

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

    \? 匹配其前面的字符0或1次,即其前面的字符可有可无

    \+ 匹配前字符1或n次,至少一次

    \{m\} 前字符只能出现m次

    \{m,n\} 前字符,至少m次,至多n次

    \{0,n\} 前字符,至多n次

    \{m,\} 前字符,至少m次

    位置锚定:

        ^ 锚定行首,用于模式的最左侧

$ 锚定行尾,用于模式的最右侧

^PATTERN$ ,用于匹配整行

^$ 空白行

^[[:space:]]*$ 空白行或者包含空白的行

单词锚定:非特殊字符

     \<root 词首锚定,用于单词的左侧,root只能出现在词首

     root\> 锚定词尾,root只能出现在单词词尾

\b 锚定单词,可以出现在词首或者词尾

\broot 锚定词首

root\b 锚定词尾

\<pattern\> 锚定完整单词

后向引用:引用前面的分组括号中的模式所匹配到的字符

分组及引用:

    \(xy\)*ab //匹配xy任意次

    分组括号中的模式匹配到的内容会被正则表达式引擎自动记录到内部的变量中,这些变量为    

    \1:从左侧其,第一个左括号,以及与之匹配的右括号之间的模式所匹配的字符

    \2:模式从左侧其,第二个括号以及与之匹配的右括号之间的模式所匹配到的字符

    \3:

        (a+(b-c)*d) //a的括号匹配到的是d后的右括号

//括号可以嵌套但是不能交叉

    示例在练习二

注意:

{} 大括号:用于限定匹配次数

() 小括号:用于分组 \1

<>尖括号:用于锚定单词

[] 中括号:限定单个字符内容

三、egrep扩展正则表达式

grep:基本正则表达式,-E,-F

egrep:扩展正则表达式,-G,-F //-F不支持正则表达式

fgrep:不支持正则表达式,-G,-E

1.egrep:

-i,-o,-v,-q,-A,-C,-B

-G:支持基本正则表达式

2.扩展正则表达式的元字符:

字符匹配:

    . 任意单个字符

    []指定范围

    [^] 指定范围外的任意单个字符

    [[:upper:]]...等

次数匹配:

    * 前字符匹配任意次,0,1或多次

    ? 前字符0或者1次 //不同,不使用转义 \

        + 前字符1或者多次 //不同

    {m} 其前的字符m次 //不同

    {m,n} 至少m次,至多n次 //不同

    {0,n} //不同

    {m,} //不同

    位置锚定等; //没有变化

^ 行首锚定

$ 行尾锚定

\<,\b 词首锚定 //基本和扩展都要加尖括号

\>,\b 词尾锚定

    分组及引用:

        () :分组;括号内的模式匹配到的字符会被记录于正则表达式引擎的内部变量中

后向引用:\1,\2,...

//只能在正则表达式中引用,不能够在bash中引用

a | b ;a或者b

C|cat:C或者cat

(c|C)at :cat或者Cat

3.基本元字符和扩展元字符不同之处:

次数匹配

    \?  ?

    \+  +

\{m,n\}  {m,n}

    位置锚定

还是都需要尖括号

    分组

    \(xy\)  (xy)

    后向引用:\1没有变

4.fgrep 不支持正则表达式元字符

当不需要用到元字符的时候,使用fgrep能更好,因为速度更快

        

四、其他文本及查看工具{wc,cut,sort,uniq,diff,patch}

wc:word count

-l :lines 行数

-w:words 词数

-c: bytes  字数

cut

-d delimiter:字段分隔符

‘ ’ 空白字符作为

-f fields:保留的字段

-f2,7

-f2-7

cut -d: -f1,2-3,7 /etc/passwd

sort

sort [OPTIONS] [FILE]...

-t CHAR 指定分隔符

-k # 用于排序指定的字段key-fileds

-n 基于数值大小进行排序,而非字符 //numeric-sort

-r reverse 反向排序

-f --ingore-case 忽略大小写

-u unique重复的行,只显示一次

-R random-sort随机排序

cut -d: -f3 /etc/passwd | sort -n

sort -t: -k3 -n /etc/passwd

uniq ;报告或者移除重复的行

cat /etc/passwd | cut -d: -f7 | sort | uniq -c

-c 统计重复次数

-d 只显示重复的行

-u 只显示没有重复的行

diff

diff [OPTION]... FILES

diff fstab fstab.new > fstab.new //生成补丁文件

patch -i fstab.patch fstab  //打补丁

patch -R -i fstab.patch fstab //还原补丁文件

diff OLD_FILE NEW_FILE > /PATH/TO/PATH_FILE

-u 使用unfied机制,即显示要修改的行的上下文,默认为3行

patch

patch [OPTIONS] -i /PATH/TO/PATCH_FILE  /PATH/TO/OLDFILE

patch /PATH/OLDFILE 《  /PATCH/TO/PATCH_FILE

[[email protected] test2]# diff -u fstab fstab.new //-u一种显示风格

--- fstab 2017-02-07 13:17:29.796429070 +0800  //---为老文件

+++ fstab.new 2017-02-07 13:11:45.572181111 +0800 //+++为新文件

@@ -1,5 +1,5 @@

-# //删除该行

+# commen1t //增加该行

 # /etc/fstab //默认显示前三行

 # Created by anaconda on Fri Dec  9 23:28:38 2016

 #

 

 #[[email protected] test2]# diff -c fstab fstab.new

*** fstab 2017-02-07 13:17:29.796429070 +0800

--- fstab.new 2017-02-07 13:11:45.572181111 +0800

***************

*** 1,5 ****

! # //!表示不同的行

  # /etc/fstab

  # Created by anaconda on Fri Dec  9 23:28:38 2016

  #

--- 1,5 ----

  

! # commen1t //该行不同

  # /etc/fstab

  # Created by anaconda on Fri Dec  9 23:28:38 2016


五、练习用例

附件一:

练习:

1.显示/etc/passwd文件中不以/bin/bash结尾的行

2.找出/etc/passwd文件中两位数或三位数

3.找出/etc/grub2.cfg文件中,以至少一个空白字符开头的,且后面非空的行

4.找出"netstat -tan" 命令的结果中以"LISTEN"后缀跟0,1或多个空白字符结尾的行

答案:

1.grep "bash$" /etc/passwd -v

2.grep "\《[0-9]\{2,3\}\>" /etc/passwd

cat /etc/passwd |grep "\《[[:digit:]]\{2,3\}\>"

3.cat /etc/grub2.cfg |grep "^[[:space:]]\+[^[:space:]]"

4.netstat -tan |grep -i "listen[[:space:]]*$"

练习二:

[[email protected] tmp]# cat aa

he loves his lover

he likes his lover

she likes his liker

she loves his liker

[ro[email protected] tmp]# 

[[email protected] tmp]# grep "\(l..e\).*\1" aa //前后限定条件相同

he loves his lover

she likes his liker

[[email protected] tmp]# grep "\(r..t\).*\1" /etc/passwd

root:x:0:0:root:/root:/bin/bash

//要使用\1,则前面要使用()括起来

    

附件二:

练习:

1.显示/etc/passwd文件中不以/bin/bash结尾的行

2.找出/etc/passwd文件中两位数或三位数

3.找出/etc/grub2.cfg文件中,以至少一个空白字符开头的,且后面非空的行

4.找出"netstat -tan" 命令的结果中以"LISTEN"后缀跟0,1或多个空白字符结尾的行

答案:

1.grep "bash$" /etc/passwd -v

2.egrep "\《[0-9]{2,3}\>" /etc/passwd

//两位或者三位是一个单词

3.egrep "^[[:space:]]+[^[:space:]]"  /etc/grub2.cfg 

4.netstat -tan |grep -i "listen[[:space:]]*$"

1.找出/proc/meminfo文件中,所有s或S开头的行,至少三种实现方式

2.显示当前系统上root,cnetos或user1用户的相关信息

3.找出/etc/rc.d/init.d/functions文件中某单词后面跟一个小括号的行

4.找出echo命令输出一绝对路径,使用egrep取出其基名

5.找出ifconfig命令中的1-255之间的数值

6.找出ifonfig命令结果中的ip地址

7.添加用户bash,testbash,basher以nologin(其shell为/sbin/nologin) ;

然后找出/etc/passwd文件中用户名同shell名的行

8.取出ifconfig eno16777736的ip地址

1. grep "^[sS].*" /proc/meminfo

egrep "^(s|S).*" /proc/meminfo

grep -i "^s" /proc/meminfo

2. egrep "^(root|test|wolf)" /etc/passwd

egrep "^\b(root|test|wolf)\b" /etc/passwd

//锚定词尾,否则和root类似的例如rootid用户也会匹配到

3.grep -E "[[:alnum:]]+\(\)" /etc/rc.d/init.d/functions 

//取出函数名

grep -E "\b[[:alnum:]]+\b\(\)" /etc/rc.d/init.d/functions 

//锚定单词

grep -E "[_[:alnum:]]+\(\)" /etc/rc.d/init.d/functions 

//可以是下划线

4. echo /etc/sysconfig |  egrep -o "[^/]+$"

//非斜线字符,出现在行尾多次

echo /etc/sysconfig/ |  egrep -o "[^/]+/?$“

[^] 取反

"^STRING" 行首

取出路径名:

echo "/etc/sysconfig/abc/dd/" |grep -o -E "/.*/"

开头是 / 中间不管什么,最后是/

5.[[email protected] ~]# 

    ifconfig | grep -o -E "\《[1-9]|[1-9][0-9|1[0-9][0-9]|2[0-4][0-9]|25[0-5]\>"

1-9 1~9

1-9|0-9|0-9 100~199

2[0-4]|[0-9] 200-249

25[0-5] 250-255

6.ifconfig | grep "\《inet\>" | cut -d‘ ‘ -f 10

7.[[email protected] ~]# grep -E "(^[^:]+\>).*\1$" /etc/passwd

cat /etc/passwd | egrep "(\《^[[:alpha:]]+\>).*\1$"

//开头是英文字母,单词,结尾也是这个单词

8.ifconfig eno16777736 | grep "\《inet\>" | cut -d‘ ‘ -f10

 

以上是关于grep与正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式 与grep

grep用法详解:grep与正则表达式 [转]

grep与基本正则表达式

grep与正则表达式

正则表达式与grep详解

grep命令与正则表达式(过滤)一