文章

Linux 正则表达式

正则表达式

1、什么是正则表达式

简单的说,正则表达式就是为处理大量的字符串及文本而定义的一套规则和方法。
正则表达式就是把人类想要查询的东西,用计算机能识别的语言表达出来的一种规则。
正则表达式主要用于三剑客(grep,sed,awk)命令支持。

2、正则表达式和通配符的区别

1.三剑客(grep,sed,awk)使用的都是正则,其他命令都使用通配符。
2.通配符是针对文件名,正则表达式针对的是文本内容。
3.* ?[] 对于通配符来说都是代表任意字符。
4.* ?[] 对于正则表达式来说意义完全不一样。

3、什么是基本正则和扩展正则

Linux三剑客的正则表达式可分为两类,具体如下:
1.基本正则表达式(BRE)对应的元字符有"^ $ . * []"。
2.扩展正则表达式(ERE)在基本正则表达式基础上增加了"() {} ? + |"等字符。

简单来说扩展正则表达式支持的符号更多,实现的功能更强大。

4、基本正则表达式常用符号

^        #以什么开头;"^hzz" 表示以hzz单词开头的行
$        #以什么结尾;"hzz$" 表示以hzz单词结尾的行
^$       #组合符号,表示空行,^$之间为空表示空行
.        #匹配任意的单个字符,匹配空格,不匹配空行
\        #转义字符,让后面的一个特殊字符失效
*        #匹配前一个字符(连续出现)0次或1次以上
.*       #组合符号,匹配所有字符
[abc]    #匹配[]内包含的任意一个字符a或b或c
[a-z]    #配置[]内包含的a-z的任意一个字符
[0-9]    #匹配[]内包含的0-9的任意一个数字
[^abc]   #取反,表示匹配除了a b c这三个字符以外的其他字符

5、基本正则表达式示例

环境准备

cat > hzz.txt << EOF
I am hzz!
I teach linux.
test123456789asd123456789

I like play games,basketball,football.
#I like Vegetables Milk
\$my blog is https://www.hanzz.red
#baidu site is https://www.baidu.com
my qq is 123456.
my phone is 11111111111.
EOF

注意:在使用正则表达式时,建议引号使用单引号。

5.1 ^ 查找以什么开头的行

[root@localhost ~]# grep '^I' hzz.txt 
I am hzz!
I teach linux.
I like play games,basketball,football.

5.2 $ 查找以什么结尾的行

[root@localhost ~]# grep '9$' hzz.txt 
test123456789asd123456789

5.3 ^$ 查找并排除空行

[root@localhost ~]# grep -v '^$' hzz.txt 
I am hzz!
I teach linux.
test123456789asd123456789
I like play games,basketball,football.
#I like Vegetables Milk
$my blog is https://www.hanzz.red
#baidu site is https://www.baidu.com
my qq is 123456.
my phone is 11111111111.

5.4 . 匹配任意单个字符

[root@localhost ~]# grep -n '.' hzz.txt 
1:I am hzz!
2:I teach linux.
3:test123456789asd123456789
5:I like play games,basketball,football.
6:#I like Vegetables Milk
7:$my blog is https://www.hanzz.red
8:#baidu site is https://www.baidu.com
9:my qq is 123456.
10:my phone is 11111111111.

5.5 \ 转义字符

[root@localhost ~]# grep '\.$' hzz.txt 
I teach linux.
I like play games,basketball,football.
my qq is 123456.
my phone is 11111111111.

5.6 * 匹配前一个字符(连续出现)0次或1次以上

[root@localhost ~]# grep 'w*' hzz.txt 
I am hzz!
I teach linux.
test123456789asd123456789

I like play games,basketball,football.
#I like Vegetables Milk
$my blog is https://www.hanzz.red
#baidu site is https://www.baidu.com
my qq is 123456.
my phone is 11111111111.

5.7 .* 匹配所有字符

[root@localhost ~]# grep '.*' hzz.txt 
I am hzz!
I teach linux.
test123456789asd123456789

I like play games,basketball,football.
#I like Vegetables Milk
$my blog is https://www.hanzz.red
#baidu site is https://www.baidu.com
my qq is 123456.
my phone is 11111111111.

[root@localhost ~]# grep '^t.*9$' hzz.txt 
test123456789asd123456789

5.8 [] 匹配[]内包含的任意一个字符

[root@localhost ~]# grep '[abc]' hzz.txt 
I am hzz!
I teach linux.
test123456789asd123456789
I like play games,basketball,football.
#I like Vegetables Milk
$my blog is https://www.hanzz.red
#baidu site is https://www.baidu.com

[root@localhost ~]# grep "[0-9]" hzz.txt 
test123456789asd123456789
my qq is 123456.
my phone is 11111111111.

[root@localhost ~]# grep '[.!]$' hzz.txt 
I am hzz!
I teach linux.
I like play games,basketball,football.
my qq is 123456.
my phone is 11111111111.

5.9 [^] 匹配除了[^]内的任意其他字符

[root@localhost ~]# grep '[^a-z]' hzz.txt 
I am hzz!
I teach linux.
test123456789asd123456789
I like play games,basketball,football.
#I like Vegetables Milk
$my blog is https://www.hanzz.red
#baidu site is https://www.baidu.com
my qq is 123456.
my phone is 11111111111.

[root@localhost ~]# grep '[^.!]$' hzz.txt 
test123456789asd123456789
#I like Vegetables Milk
$my blog is https://www.hanzz.red
#baidu site is https://www.baidu.com

[root@localhost ~]# grep '^#.*[^.!]$' hzz.txt 
#I like Vegetables Milk
#baidu site is https://www.baidu.com

6、扩展正则表达式常用符号

+        #匹配前面一个字符1次或多次
[:/]+    #匹配前面括号内的":"或"/"字符1次或多次
?        #匹配前面一个字符0次或1次
|        #表示或者
()       #分组过滤,被括起来的内容表示一个整体,另外()中的内容可以被后面的\n引用,n为数字,表示引用第几个括号中的内容
\n       #n代表数字,表示引用前面第几个()中的内容,例如(abc)\1 表示匹配abcabc
a{n,m}   #匹配前面一个字符最少n次,最多m次
a{n,}    #匹配前面一个字符最少n次
a{,m}    #匹配前面一个字符最多m次
a{n}     #匹配前面一个字符刚好n次

7、扩展正则表达式示例

7.1 + 匹配前面一个字符1次或多次

[root@localhost ~]# egrep 'w+' hzz.txt 
$my blog is https://www.hanzz.red
#baidu site is https://www.baidu.com

[root@localhost ~]# egrep '[:/]+' hzz.txt 
$my blog is https://www.hanzz.red
#baidu site is https://www.baidu.com

7.2 ? 匹配前面一个字符0次或1次

[root@localhost ~]# egrep '1?' hzz.txt 
I am hzz!
I teach linux.
test123456789asd123456789

I like play games,basketball,football.
#I like Vegetables Milk
$my blog is https://www.hanzz.red
#baidu site is https://www.baidu.com
my qq is 123456.
my phone is 11111111111.

7.3 | 或者

[root@localhost ~]# egrep '^I|\.$' hzz.txt 
I am hzz!
I teach linux.
I like play games,basketball,football.
my qq is 123456.
my phone is 11111111111.

7.4 () 分组过滤

[root@localhost ~]# egrep '(w)\1' hzz.txt 
$my blog is https://www.hanzz.red
#baidu site is https://www.baidu.com

[root@localhost ~]# egrep '(w)\1\1' hzz.txt 
$my blog is https://www.hanzz.red
#baidu site is https://www.baidu.com

[root@localhost ~]# egrep '(123456).*\1' hzz.txt 
test123456789asd123456789

7.5 {} 匹配前面一个字符的次数

[root@localhost ~]# egrep -w '[0-9]{11}' hzz.txt 
my phone is 11111111111.

[root@localhost ~]# egrep -w '[0-9]{6,10}' hzz.txt 
my qq is 123456.

7.6 扩展正则表达式组合使用

  • 查找出现连续字母的行。
[root@localhost ~]# egrep '([a-z])\1{1,}' hzz.txt 
I am hzz!
I like play games,basketball,football.
$my blog is https://www.hanzz.red
#baidu site is https://www.baidu.com
my qq is 123456.

[root@localhost ~]# egrep '([a-z])\1+' hzz.txt 
I am hzz!
I like play games,basketball,football.
$my blog is https://www.hanzz.red
#baidu site is https://www.baidu.com
my qq is 123456.
  • 查找同一个字母连续出现3次的行。
[root@localhost ~]# egrep -w '([a-z])\1{2,}' hzz.txt 
$my blog is https://www.hanzz.red
#baidu site is https://www.baidu.com
  • 查找文件内容中出现的所有域名,xxx.xxx.xxx
[root@localhost ~]# egrep -wo '[a-Z0-9]+\.[a-Z0-9]+\.[a-Z0-9]+' hzz.txt 
www.hanzz.red
www.baidu.com
  • 查找文件内容中出现的所有链接,http(s)://xxx.xxx.xxx/xxx/xxx。
准备环境:
echo 'http://www.hanzz.red/123abc hzz' >> hzz.txt
echo 'https://www.baidu.com/aaa/bbb/ccc hzz' >> hzz.txt

[root@localhost ~]# egrep -wo 'https?://[a-Z0-9]+\.[a-Z0-9]+\.[a-Z0-9]+[/a-Z0-9]{0,}' hzz.txt 
https://www.hanzz.red
https://www.baidu.com
http://www.hanzz.red/123abc
https://www.baidu.com/aaa/bbb/ccc

8、正则表达式练习

  • 查找某个进程是否存在。
[root@localhost ~]# ps aux | grep "sshd" | grep -v "grep"
root      2409  0.0  0.0 106068   356 ?        Ss   10月21   0:02 /usr/sbin/sshd -D
root     15986  0.0  0.3 148984  5772 ?        Ss   11月16   0:00 sshd: root@notty
root     17918  0.3  0.3 149132  6228 ?        Ss   11月16   0:36 sshd: root@pts/0,pts/1

[root@localhost ~]# ps aux | grep '[s]shd'
root      2409  0.0  0.0 106068   356 ?        Ss   10月21   0:02 /usr/sbin/sshd -D
root     15986  0.0  0.3 148984  5772 ?        Ss   11月16   0:00 sshd: root@notty
root     17918  0.3  0.3 149132  6228 ?        Ss   11月16   0:36 sshd: root@pts/0,pts/1
  • 去除配置文件中所有的注释行以及空行
[root@localhost ~]# egrep -v '^#|^$' hzz.txt 
I am hzz!
I teach linux.
test123456789asd123456789
I like play games,basketball,football.
$my blog is https://www.hanzz.red
my qq is 123456.
my phone is 11111111111.
http://www.hanzz.red/123abc hzz
https://www.baidu.com/aaa/bbb/ccc hzz
  • 查看磁盘sda的使用率。
[root@localhost ~]# df -h | grep 'sda' | egrep -o '[0-9]+%' | egrep -o '[0-9]+'
23
  • 取出网卡的IP地址。
[root@localhost ~]# ip a show eth0 | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | head -1
172.17.57.156
  • 统计/etc/passwd所有shell为nologin的行并只显示用户名。
[root@localhost ~]# grep 'nologin' /etc/passwd | egrep -o '^[a-Z0-9-]+'
bin
daemon
adm
lp
mail
......
  • 查找/dev/sda的uuid。
[root@localhost ~]# blkid | grep 'sda' | egrep -o ' UUID="[a-zA-Z0-9-]+"' | egrep -o '[a-zA-Z0-9-]{5,}'
5Cil5v-j7MN-19of-cEcy-nBgt-U6I1-hidC7y
273327b7-8bbf-4951-8c02-c06c5c00a627
License: