【Linux正则表达式之grep&egrep】

Linux正则表达式

Regual Express REGEXP:

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

其中正则表达式分为两种:

  • ①.基本正则表达式:BRE
  • ②.扩展的正则表达式:ERE
  • 正则表达式的意义:
# 正则表达式的意义:
> 处理大量的字符串
> 处理文本

通过特殊符号的辅助,可以让Linux管理快速过滤,替换、处理所需要的字符串、文本,让工作更加快捷有效。

- 配置文件
- 程序代码
- 命令输出结果
- 日志文件
  • 正则表达式是一套规则和方法
  • 正则工作时以单位进行,一次处理一行
  • 正则表达式化繁为简,提高工作效率
  • Linux仅三大剑客(sed、grep、awk)支持,其它命令无法使用

正则表达式的应用非常广泛,如:python、Java、perl等,Linux下普通命令无法使用正则表达式、只能使用三剑客(sed、grep、awk)

通配符是大部分普通命令都支持的,用于查找文件或目录,而正则表达式是通过三剑客命令在文件中过滤内容

Linux三剑客:

文本处理工具,均支持正则表达式引擎

  • grep:文本过滤工具,(模式pattern工具)
  • sed:stream editor,流编辑器;文本编辑工具
  • awk:Linux的文本报告生成器(格式化文本),Linux上是gawk
  • 正则表达式分类:

Linux三剑客主要分两类

  • 基本正则表达式(BRE、basic、regular、expression)
BRE对应的元字符有 ^$.[]*
  • 扩展正则表达式(BRE、extended、regular expression)
ERE在BRE基础上,增加上 (){}?+| 等字符
(1)、✅💯基本正则表达式BRE集合
  • 匹配字符
  • 匹配次数
  • 位置锚定
符号作用
^尖角号,用于模式最左侧,如"^oldboy",匹配以oldboy单词开头的行
$美元符,用于匹配模式的最右侧,如"oldboy$",表示以oldboy单词结尾的行
^$组合符,表示空行
.匹配任意一个且只有一个字符,不能匹配空行
\转义字符,让特殊含义的字符,现出原型,还原本意,例如 \ . 代表小数点
*匹配前一个字符(连续出现)0或1次以上,重复0次代表空,即匹配所有内容
.*组合符,匹配所有内容
^.*组合符,匹配任意多个字符开头的内容
.*$组合符,匹配以任意多个字符结尾的内容
[abc]匹配[]集合内的任意一个字符,a或b或c,可以写[a-c]
[^abc]匹配除了后面的任意字符,a或b或c,表示对[abc]的取反
(2)、✅💯扩展正则表达式ERE集合

扩展正则必须使用grep -E才能生效

字符作用
+匹配前一个字符1次或多次
[: /]+匹配括号内的":“或者”/"字符1次或多次
?匹配前一个字符0次或1次
\表示或者,同时过滤多个字符串
()分组过滤,被括起来的内容表示一个整体
a{n,m}匹配前一个字符最少n次,最多m次
a{n,}匹配前一个字符最少n次
a{n}匹配前一个字符正好n次
a{,m}匹配前一个字符最多m次
# Tips:
> grep 命令需要使用参数-E则可支持正则表达式
> egrep 平常不推荐使用,使用grep -E替代
> grep 不加参数,需要在特殊字符前加"\"反斜杠,标识为正则
(3)、🧀grep

grep:

全拼:Global search REgular expression and Print out the line

作用:

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

模式:

由正则表达式的 元字符文本字符 编写出的 过滤条件;

# 语法:
grep [options] [pattern] file
命令 参数 匹配模式 文件数据

-i :ignorecase,忽略字符的大小写
-o :进现实匹配到的字符串本身;
-v :--invert-match:显示不能被模式匹配到的行
-E :支持使用扩展的正则表达式
-q :--quiet ,--silent ;静默模式,即不输出任何信息;

grep 命令是Linux系统中最重要的命令之一,功能是从文本文件管道数据流中筛选匹配的数据,如果再配合正则表达式,功能是十分强大,是Linux运维人员必备的指令

  • grep的匹配模式:
参数选项解释说明
-v排除匹配结果
-n显示匹配行与行号
-i不区分大小写
-c只统计匹配的行数
-E使用egrep命令(扩展的正则表达式)
–color=auto为grep的结果添加颜色
-w只匹配过滤的单词
-o只输出匹配的内容
# -i:查找匹配字符串不区分大小写输出

[root@kvm01 ~]# cat passwd | grep -i "root"
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

# -n:查找"root"字符串所在的行并且不区分大小写、加上行号输出

[root@kvm01 ~]# cat passwd | grep -i -n "root"
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin

# -v:找出没有login和root的行
[root@kvm01 ~]# grep -v "root|login" /etc/passwd                       
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
hsqldb:x:96:96::/var/lib/hsqldb:/sbin/nologin
mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin

# -v -c:找出没有"root","login"的行并统计输出的行数
[root@kvm01 ~]# grep -v -c "root|login" /etc/passwd 
21

# -E -i:同时过滤出有"root"和"sync"的行
[root@kvm01 ~]# grep -E -i "root|sync" /etc/passwd
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
operator:x:11:0:operator:/root:/sbin/nologin

# -n -o:匹配带有"login"的行,仅输出需要查找的字符并带上行号
[root@kvm01 ~]# grep "login" -n -o /etc/passwd
2:login
3:login
4:login
5:login
9:login
10:login
11:login
12:login
13:login
14:login
15:login
16:login
17:login
18:login
19:login
20:login
21:login

# -w:对字符串进行精准匹配
[root@kvm01 ~]# grep "root" /etc/passwd -w
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

# -E -v:去除掉空白行和注释的行
[root@kvm01 ~]# grep -Ev "^#|^$" /etc/profile
pathmunge () {
    case ":${PATH}:" in
        *:"$1":*)
            ;;
        *)
            if [ "$2" = "after" ] ; then
                PATH=$PATH:$1
            else
                PATH=$1:$PATH
            fi
    esac
}
if [ -x /usr/bin/id ]; then
    if [ -z "$EUID" ]; then
        # ksh workaround
        EUID=`/usr/bin/id -u`
        UID=`/usr/bin/id -ru`
    fi
    USER="`/usr/bin/id -un`"
    LOGNAME=$USER
    MAIL="/var/spool/mail/$USER"
fi
if [ "$EUID" = "0" ]; then
    pathmunge /usr/sbin
    pathmunge /usr/local/sbin
else
    pathmunge /usr/local/sbin after
    pathmunge /usr/sbin after
fi
HOSTNAME=`/usr/bin/hostname 2>/dev/null`
HISTSIZE=1000
if [ "$HISTCONTROL" = "ignorespace" ] ; then
    export HISTCONTROL=ignoreboth
else
    export HISTCONTROL=ignoredups
fi
export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL
if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
    umask 002
else
    umask 022
fi
for i in /etc/profile.d/*.sh /etc/profile.d/sh.local ; do
    if [ -r "$i" ]; then
        if [ "${-#*i}" != "$-" ]; then 
            . "$i"
        else
            . "$i" >/dev/null
        fi
    fi
done
unset i
unset -f pathmunge
export TOMCAT_HOME=/opt/tomcat
export TERM=xterm
# grep输出默认带颜色
[root@kvm01 ~]# cat .bashrc | grep alias | grep grep
alias grep='grep --color=auto'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'

# 在全局变量中添加:把我们想要筛选输出的信息带上颜色
$ echo "alias grep='grep --color=auto'" >> ~/.bashrc && echo "alias egrep='egrep --color=auto'" >> ~/.bashrc && echo "alias fgrep='fgrep --color=auto'" >> ~/.bashrc

(4)、Grep实践
  • 正则表达式grep实践:

准备测试文件:

cat <<EOF > luffy.txt
I am oldboy teacher
I teach linux.
I like python.

My qq is 877348180

My name is chaoge.

Our school website is http://oldboy.com


EOF

^符号:

1.输出所有以m开头的行

[root@kvm01 ~]# grep -i -n "^m" luffy.txt 
5:My qq is 877348180
7:My name is chaoge.

2.输出所有以i开头的行

[root@kvm01 ~]# grep -i -n "^i" luffy.txt 
1:I am oldboy teacher
2:I teach linux.
3:I like python.
# Tips:
> 在Linux平台下,所有的文本行结尾都有一个$符
> 可以用cat -A查看文件是否有空格
> vim编辑器下可以用:set list查看空行
[root@kvm01 ~]# cat -A luffy.txt 
I am oldboy teacher$
I teach linux.$
I like python.$
$
My qq is 877348180$
$
My name is chaoge.$
$
Our school website is http://oldboy.com$
$
$

在这里插入图片描述

$符:

1.输出以"."结尾的行

# 此处添加\(转义符)意味让特殊含义的字符"."还原本意
[root@kvm01 ~]# grep -n "\.$" luffy.txt 
2:I teach linux.
3:I like python.
7:My name is chaoge.

# 如果使用".$"直接匹配则会将所有非空行结尾的行匹配出来,如果添加了\转移符则不会
[root@kvm01 ~]# grep -n ".$" luffy.txt 
1:I am oldboy teacher
2:I teach linux.
3:I like python.
5:My qq is 877348180
7:My name is chaoge.
9:Our school website is http://oldboy.com

2.找出所有允许登录的用户,解释器是/bin/bash的行

[root@localhost ~]# grep -n "/bin/bash$" /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
20:gpm:x:1000:1000::/home/gpm:/bin/bash
30:ztx:x:1001:1001::/home/ztx:/bin/bash
31:grj:x:1002:1002::/home/grj:/bin/bash
32:cl:x:1003:1003::/home/cl:/bin/bash

# 只输出查找的关键字符并以行号输出
[root@localhost ~]# grep -o -n "/bin/bash$" /etc/passwd 
1:/bin/bash
20:/bin/bash
30:/bin/bash
31:/bin/bash
32:/bin/bash

3.找出不允许登录的用户

[root@localhost ~]# grep -v -n "/bin/bash$" /etc/passwd    
2:bin:x:1:1:bin:/bin:/sbin/nologin
3:daemon:x:2:2:daemon:/sbin:/sbin/nologin
4:adm:x:3:4:adm:/var/adm:/sbin/nologin
5:lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6:sync:x:5:0:sync:/sbin:/bin/sync
7:shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8:halt:x:7:0:halt:/sbin:/sbin/halt
9:mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10:operator:x:11:0:operator:/root:/sbin/nologin
11:games:x:12:100:games:/usr/games:/sbin/nologin
12:ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
13:nobody:x:99:99:Nobody:/:/sbin/nologin
14:systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
15:dbus:x:81:81:System message bus:/:/sbin/nologin
16:polkitd:x:999:998:User for polkitd:/:/sbin/nologin
17:sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
18:postfix:x:89:89::/var/spool/postfix:/sbin/nologin
19:chrony:x:998:996::/var/lib/chrony:/sbin/nologin
21:unbound:x:997:993:Unbound DNS resolver:/etc/unbound:/sbin/nologin
22:rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
23:qemu:x:107:107:qemu user:/:/sbin/nologin
24:gluster:x:996:992:GlusterFS daemons:/run/gluster:/sbin/nologin
25:saslauth:x:995:76:Saslauthd user:/run/saslauthd:/sbin/nologin
26:radvd:x:75:75:radvd user:/:/sbin/nologin
27:tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
28:rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
29:nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
33:mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin
34:apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
35:nginx:x:994:990:Nginx web server:/var/lib/nginx:/sbin/nologin
36:named:x:25:25:Named:/var/named:/sbin/nologin

^$组合符:

1.找出文件的空行,以及行号

[root@kvm01 ~]# grep "^$" luffy.txt 





[root@kvm01 ~]# 

#添加上行号
[root@kvm01 ~]# grep "^$" luffy.txt -n
4:
6:
8:
10:
11:

.点符号:

“.” 点表示任意一个字符,有且只有一个,不包含空行

[root@kvm01 ~]# grep -i -n "." luffy.txt 
1:I am oldboy teacher
2:I teach linux.
3:I like python.
5:My qq is 877348180
7:My name is chaoge.
9:Our school website is http://oldboy.com

# 找出任意的两个带s结尾的字符
[root@kvm01 ~]# grep -i -n ".s" luffy.txt 
5:My qq is 877348180
7:My name is chaoge.
9:Our school website is http://oldboy.com

\转义字符:

# 找出文本中所有的点".",如果"."点号不加转义符\则这个点号则以正则表达式执行
[root@kvm01 ~]# grep "\." luffy.txt 
I teach linux.
I like python.
My name is chaoge.
Our school website is http://oldboy.com

*符:

# 找出前一个字符0次或多次,找出文中出现"i"的0次或多次
[root@kvm01 ~]# grep "i*" luffy.txt
I am oldboy teacher
I teach linux.
I like python.

My qq is 877348180

My name is chaoge.

Our school website is http://oldboy.com


[root@kvm01 ~]# grep "i*" luffy.txt -o
i
i
i
i
i
i

*.组合符号:

*.组合符号:

.表示任意一个字符,*表示匹配前一个字符0次或多次,因此放一起,代表匹配所有内容,以及空格

# 表示匹配所有的内容包括空格
[root@kvm01 ~]# grep ".*" luffy.txt 
I am oldboy teacher
I teach linux.
I like python.3

My qq is 877348180

My name is chaoge.

Our school website is http://oldboy.com


# ^.*o符:
^ 以某字符为开头
.任意0或多个字符
.*代表匹配所有内容

o普通字符,一直到字母o结束
这种匹配相同字符到最后一个字符的特点,称之为贪婪匹配
# 匹配前面以I开头,一直匹配到o结尾
[root@kvm01 ~]# grep "I.*o" luffy.txt 
I am oldboy teacher
I like python.

# 显示匹配到的字符串
[root@kvm01 ~]# grep "I.*o" luffy.txt -o
I am oldbo
I like pytho

# 匹配不管以什么开头的字符,以e结尾并将结果输出
[root@kvm01 ~]# grep ".*e" luffy.txt 
I am oldboy teacher
I teach linux.
I like python.
My name is chaoge.
Our school website is http://oldboy.com

# 显示匹配到的字符串
[root@kvm01 ~]# grep ".*e" luffy.txt -o
I am oldboy teache
I te
I like
My name is chaoge
Our school website

[abc]中括号:

中括号表达式:

中括号表达式,[abc]表示匹配中括号中的任意一个字符,a或b或c

常见形式如下:

# 匹配所有的小写字母
[root@kvm01 ~]# grep '[a-z]' luffy.txt 
I am oldboy teacher
I teach linux.
I like python.
My qq is 877348180
My name is chaoge.
Our school website is http://oldboy.com

# 仅显示匹配字符
[root@kvm01 ~]# grep '[a-z]' luffy.txt -o
a
m
o
... ...条目过多不予展示

# 匹配文件里所有大小写字母
[root@kvm01 ~]# grep '[a-Z]' luffy.txt 
I am oldboy teacher
I teach linux.
I like python.
My qq is 877348180
My name is chaoge.
Our school website is http://oldboy.com

# 仅显示匹配字符
[root@kvm01 ~]# grep '[a-Z]' luffy.txt -o
I
a
m
... ...条目过多不予展示

# 过滤除了0-5之间的内容(3\4\0被过滤了)
[root@kvm01 ~]# grep "[^0-5]" luffy.txt 
I am oldboy teacher
I teach linux.
I like python.
My qq is 877348180
My name is chaoge.
Our school website is http://oldboy.com

grep参数-o:

使用"-o"选项,可以只显示被匹配到的关键字,而不是将整行的内容都输出

虽然wc -l和grep -c 都是将匹配的行数显示出来,但是wc -l命令是将过滤出来的条目统计有多少行,grep -c 则是统计匹配的字符串的数量(其中就有两个相同的字符串在同一行,grep -c按照行数输出而不是字符串相匹配的数量输出)

# 显示有多少个字符a
[root@kvm01 ~]# grep -o "a" luffy.txt | wc -l
5
(5)、Egrep实践

此处使用grep -E进行扩展实践正则,egrep官网已经启用

# 匹配一次或者多次i这个字符并输出
[root@kvm01 ~]# grep -E "i+" luffy.txt 
I teach linux.
I like python.
My qq is 877348180
My name is chaoge.
Our school website is http://oldboy.com

# 匹配一次或者多次ch这个字符并输出
[root@kvm01 ~]# grep -E "ch+" luffy.txt 
I am oldboy teacher
I teach linux.
My name is chaoge.
Our school website is http://oldboy.com
  • 准备测试文件:
[root@kvm01 ~]# cat <<EOF > test.txt
g0000000000d
god
gd
g00000d
EOF

?符:

匹配前一个字符0次或1次

要么这个字符只出现过一次要么就没有出现过

[root@kvm01 ~]# grep -E 'go?d' test.txt 
god
gd4

|符:

竖线 | 在正则中是或者的意思

找出系统中的txt文件,且名字里包含a或者b的字符

# 查找/目录下的txt文件,并且是包含了a和x的文件

[root@kvm01 ~]# find / -name "*.txt" | grep -E "a|x"
/etc/pki/nssdb/pkcs11.txt
/root/luffy.txt
/root/test.txt
/var/cache/yum/x86_64/7/base/mirrorlist.txt
/var/cache/yum/x86_64/7/timedhosts.txt
... ... 内容过多不予展示

{}小括号:

{}小括号:

将一个或者多个字符捆绑在一起,当做一个整体来处理;

  • 小括号内的内容可以被后面的"\n"正则引用,n为数字,表示引用第几个括号的内容
    • \1:表示从左侧起,第一个括号中的模式所匹配到的字符
    • \2:从左侧起,第二个括号中的模式所匹配到的字符串
  • 准备两份测试文件:
cat <<EOF >test.txt
g0000000000d
god
gd
goooood
glad
good
goooood
EOF

cat <<EOF >lovers.txt
I like my lover.
I love my lover.
He likes his lovers.
He love his lovers.
EOF
  • 找出包含good和glad的行
[root@kvm01 ~]# grep -E "g(oo|la)d" test.txt 
glad
good
  • 分组之向后引用
# 匹配以l开头e结尾的任何内容并以"\1"分组向后引用
[root@kvm01 ~]# grep -E "(l..e).*\1" lovers.txt 
I love my lover.
He love his lovers.

# 仅显示过滤的字符
[root@kvm01 ~]# grep -E -o "(l..e).*\1" lovers.txt 
love my love
love his love

{n,m}匹配次数:

重复前一个字符各种次数,可以通过-o参数显示明确的匹配过程

# 准备测试文件
cat <<EOF >test.txt
yyyyyyyyyu
cccccccchao
yyyyu
yuchaooooooo
EOF

# 匹配y字符,最少2次,最多4次
[root@kvm01 ~]# grep -E "y{2,4}" test.txt   
yyyyyyyyyu
yyyyu

# 显示这个字符串被匹配的次数
[root@kvm01 ~]# grep -E "y{2,4}" test.txt  -o
yyyy
yyyy
yyyy

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值