文章目录
一、Linux正则表达式与三剑客知识
1.什么是正则表达式?
简单地说,正则表达式就是为处理大量的字符串及文本而定义的一套规则和方法。假设"@"代表"Iam”, "!"代表"buffes”,则执行 echo "@!“的结果就是输出“I am buffes”。通过这些特殊符号的辅助,管理员就可以快速过滤、替换或输出需要的字符串,让Linux运维工作更高效。
Linux三剑客的正则表达式有如下几个特点:
为处理大量文本及字符串而定义的一套规则和方法。
其工作时以行为单位进行,即一次处理一行。
通过正则表达式可以将复杂的处理任务化繁为简,提高操作Linux的效率。
仅被三剑客(grep/egrep、sed、awk)命令支持,其他命令无法使用。
2.为什么要学习正则表达式?
实际企业中,运维工程师在做Linux运维工作时,通常都会面对大量带有字符串的内容,比如文本配置、程序、命令输出及日志文件等,而我们经常会有迫切的需要,比如,要从大量的字符串内容中查找符合工作需要的特定的字符串,这就要靠正则表达式了。因此,可以说正则表达式就是为过滤这样特殊字符串而生的!
例如:要从ifconfig的输出中取出IP地址段内容,就可以利用如下命令配合正则表达式字符匹配实现。
[root@buffes ~]# ifconfig eth0 | sed -rn '2s#".*addr: (.*) Bc.*$#\1#gp'#<=Centos6 下命令。
10.0.0.7
[root@buffes ~]# ifconfig eth0 | sed -rn '2s#",*inet (.*) net.*$#\1#gp'#<==Centos7下命令。
10.0.0.7
3.有关正则表达式容易混淆的事项
正则表达式的应用非常广泛,存在于各种语言中,例如: Python、 Java、 Perl (PCRE)等。但是,本文讲的是Linux系统运维工作中的正则表达式,即Linux正则表达式,应用 正则表达式的命令就是grep(egrep), sed.awk,换句话说, Linux三剑客要想工作更高效,那一定离不开正则表达式的配合。注意,其他普通命令正常情况下无法使用正则表达式。
正则表达式和前文讲解的通配符、特殊字符是有本质区别的,正则在Linux中是通过 三剑客命令在文件(或数据流)中过滤内容的。而通配符是大部分普通命令都支持的,它主要是用来查找文件或目录的,比如说查以txt结尾的文件时,就是用"*.txt"这样的字符串匹配。这一点伙伴们要注意。
4.学习正则表达式注意事项
在学习正则表达式之前,先来看看下面几点说明:
(1)Linux正则表达式是按照行为单位进行处理的。
(2)正则表达式仅适合三剑客命令,为了方便讲解,本章更多使用grep和egrep命令进行 演示,并且还会建议给它们加上一个别名配置,示例如下:
alias grep='grep --color=auto'
alias egrep='egrep --color=auto' #<==配置后会把匹配上的内容用红色显示,仅CentOS6 需要配置。
(3)注意LC_ALL环境变量的设置,建议为:
export LC_ALL=C #<==配置后操作时不会出现异常匹配情况。
完整的处理及生效命令为:
cat >>/etc/profile<<EOF #<==注意 EOF 后面不要有多余的空格。
alias grep='grep --color=auto'
alias egrep='egrep --color=auto'
export LC_ALL=C
EOF #<==注意 EOF 前后都没有空格或其他符号。
source /etc/profile #<==使修改的内容生效。
5. 正则表达式的分类
Linux三剑客的正则表达式分为两类,即:
1) 基本正则表达式(BRE, basic regular expression)
BRE 对应的元字符有“^S.[]*”。
2) 扩展正则表达式(ERE, extended regular expression)
ERE在BRE的基础上增加了“0{)?+1”等字符。
5.1 基本的正则表达式(BRE)集合
字符 | 作用 |
---|---|
^ | 尖角号,用法为^koboid,表示匹配以koboid单词开头的行 |
$ | 美元符,用法为koboid$,表示匹配以koboid单词结尾的行 |
^$ | 组合符,表示空行,逻辑解释就是以^结尾的行,或者以$开头的行 |
. | 点号,表示匹配任意一个且只有一个字符(但是不能匹配空行) |
\ | 转义字符,让有特殊含义的字符脱掉马甲,现出原形,如.只表示小数点 |
* | 重复前一个字符(连续出现)0次或N次 |
.* | 组合符,匹配所有内容 |
^.* | 组合符,匹配以任意多个字符开头的内容 |
.*$ | 组合符,以任意多个字符结尾的内容 |
[abc] | 匹配[]集合内的任意一个字符a或b或c;[abc]也可写成[a-c] |
[^abc] | 匹配不包含^ 后的任意字符a或b或c,这里的^ 表示对[abc]的取反,^不能用 ! 替代 |
测试实验:
^ 尖角号,用法为^koboid,表示匹配以koboid单词开头的行
[root@buffes test]# grep ^I buffes.txt #输出以I开头的行
I am buffes teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
[root@buffes test]# ls -l ~|grep ^d #输出以d开头的行
drwxr-xr-x. 2 1000 root 33 Jul 1 2030 abc
drwxr-xr-x. 2 root root 45 Jun 6 2019 girlLove
drwxr-xr-x. 3 root root 17 May 8 2021 buffes_dir
drwxr-xr-x. 2 root root 24 May 25 11:24 test
$ 美元符,用法为buffes$,表示匹配以buffes单词结尾的行
[root@buffes test]# grep m$ buffes.txt #输出以m结尾的行
our site is http://www.buffes.cn
[root@buffes test]# ls -lF ~|grep /$
drwxr-xr-x. 2 1000 root 33 Jul 1 2030 abc/
drwxr-xr-x. 2 root root 45 Jun 6 2019 girlLove/
drwxr-xr-x. 3 root root 17 May 8 2021 buffes_dir/
drwxr-xr-x. 2 root root 24 May 25 11:24 test/
^$ 组合符,表示空行,逻辑解释就是以^结尾的行,或者以$开头的行
[root@buffes test]# cat buffes.txt -n
1 I am buffes teacher!
2 I teach linux.
3
4 I like badminton ball ,billiard ball and chinese chess!
5 our site is http://www.buffes.cn
6 my qq num is 1234567.
7
8 not 1234567.
9 my god ,i am not buffes,but buffes!
[root@buffes test]# grep ^$ buffes.txt
[root@buffes test]# grep -n ^$ buffes.txt #输出空行并打印行号
3:
7:
. 点号,表示匹配任意一个且只有一个字符(但是不能匹配空行)
[root@buffes test]# grep . buffes.txt
I am buffes teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
our site is http://www.buffes.cn
my qq num is 1234567.
not 1234567.
my god ,i am not buffes,but buffes!
[root@buffes test]# grep -n . buffes.txt
1:I am buffes teacher!
2:I teach linux.
4:I like badminton ball ,billiard ball and chinese chess!
5:our site is http://www.buffes.cn
6:my qq num is 1234567.
8:not 1234567.
9:my god ,i am not buffes,but buffes!
\ 转义字符,让有特殊含义的字符脱掉马甲,现出原形,如.只表示小数点
[root@buffes test]# grep "\." buffes.txt #匹配带点的行
I teach linux.
our site is http://www.buffes.cn
my qq num is 1234567.
not 1234567.
[root@buffes test]# grep "\.$" buffes.txt #匹配以点结尾的行
I teach linux.
my qq num is 1234567.
not 1234567.
[root@buffes test]# grep ".$" buffes.txt #匹配以任意一个字符结尾的行
I am buffes teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
our site is http://www.buffes.cn
my qq num is 1234567.
not 1234567.
my god ,i am not buffes,but buffes!
*
重复前一个字符(连续出现)0次或N次
0*
空
0
00
00000
[root@buffes test]# grep "0*" buffes.txt
I am buffes teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
our site is http://www.buffes.cn
my qq num is 1234567.
not 1234567.
my god ,i am not oldbey,but buffes!
[root@buffes test]# grep "00*" buffes.txt
my qq num is 1234567.
not 1234567.
注意,当重复0次的时候,表示啥也没有(空),即匹配所有内容
.*
组合符,匹配所有内容
[root@buffes test]# grep ".*" buffes.txt
I am oldboy teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
our site is http://www.buffes.cn
my qq num is 1234567.
not 1234567.
my god ,i am not buffes,but BUFFES!
^.* 组合符,匹配以任意多个字符开头的内容
.*$ 组合符,以任意多个字符结尾的内容
[abc] 匹配[]集合内的任意一个字符a或b或c;[abc]也可写成[a-c]
[root@buffes test]# grep "[a-z0-9A-Z\.\!:,/]" buffes.txt
I am buffes teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
our site is http://www.buffes.cn
my qq num is 1234567.
not 1234567.
my god ,i am not buffes,but buffes!
[root@buffes test]# grep "." buffes.txt
I am buffes teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
our site is http://www.buffes.cn
my qq num is 1234567.
not 1234567.
my god ,i am not buffes,but BUFFES!
[^abc] 匹配不包含^
后的任意字符a或b或c,这里的^
表示对[abc]的取反,^不能用!替代
[root@buffes test]# grep "[a-z0-9A-Z]" buffes.txt
I am buffes teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
our site is http://www.buffes.cn
my qq num is 1234567.
not 1234567.
my god ,i am not oldbey,but buffes!
[root@buffes test]#
[root@buffes test]#
[root@buffes test]#
[root@buffes test]#
[root@buffes test]# grep "[^a-z0-9A-Z]" buffes.txt
I am buffes teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
our site is http://www.buffes.cn
my qq num is 1234567.
not 1234567.
my god ,i am not buffes,but buffes!
6. 正则表达式测试题
1.过滤/etc/passwd中以nologin结尾的行。
grep "nologin$" /etc/passwd
2.过滤/etc/passwd中以o开头的行。
grep "^o" /etc/passwd
3.过滤/etc/passwd中至少含有1个0字符串的行。
grep "00*" /etc/passwd
4.过滤/etc/passwd中的空行。
grep "^$" /etc/passwd
5.过滤/etc/目录中(不含子目录)下的所有文件。
ls -l /etc|grep "^-"
6.过滤/etc/services中含有点号的行。
grep "\." /etc/services
7. 扩展正则
字符 | 作用 |
---|---|
+ | 匹配前一个字符1次或多次 |
? | 匹配前一个字符0次或1次 |
| | 表示或者,即同时过滤多个字符串 |
() | 分组过滤被括起来的东西表示一个整体 另外()的内容可以被后面的\n引用,n为数字,表示引用第几个括号的内容 |
\n | 引用前面()小括号里的内容,例如:(aa)\1,匹配aaaa |
a{n,m} | 匹配前一个字符最少n次,最多m次 |
a{n,} | 匹配前一个字符最少n次 |
a{n} | 匹配前一个字符正好n次 |
a{,m} | 匹配前一个字符最多m次 |
+ 匹配前一个字符1次或多次
和*区别,*可以匹配0次。
grep "0*" buffes.txt #匹配0个0,或1个0或多个0
egrep "0+" buffes.txt #1个0或多个0
[root@buffes test]# grep "0*" buffes.txt
I am buffes teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
our site is http://www.buffes.cn
my qq num is 1234567.
not 1234567.
my god ,i am not buffes,but buffes!
[root@buffes test]# egrep "0+" buffes.txt
my qq num is 1234567.
not 1234567.
[:/]+
匹配括号内的:或/字符1次或多次
[root@buffes test]# cat a.txt
buffes
[root@buffes test]# egrep -o "." a.txt
o
l
d
b
o
y
[root@buffes test]# egrep "[:/]+" buffes.txt
our site is http://www.buffe.cn
:::
///
:d::f
/etc/buffes//
[root@buffes test]# egrep "[:/]" buffes.txt
our site is http://www.buffe.cn
:::
///
:d::f
/etc/buffes//
? 匹配前一个字符0次或1次
[root@buffes test]# egrep "0?" buffes.txt
I am buffes teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
our site is http://www.buffes.cn
my qq num is 1234567.
not 1234567.
my god ,i am not buffes,but buffes!
:::
///
:d::f
/etc/buffes//
| 表示或者,即同时过滤多个字符串
[root@buffes test]# egrep "000|buffes" buffes.txt
I am buffes teacher!
our site is http://www.buffes.cn
my qq num is 1234567.
not 1234567.
/etc/buffes//
()分组过滤被括起来的东西表示一个整体
另外()的内容可以被后面的\n引用,n为数字,表示引用第几个括号的内容
\n 引用前面()小括号里的内容,例如:(aa)\1,匹配aaaa
[root@buffes test]#
[root@buffes test]# egrep "(0)(0)\1\2" buffes.txt
not 1234567.
\1可以取出第1个括号的内容
\2可以取出第2个括号的内容。
.....
sed命令
(下面几个没啥用)
a*
a+
a{n,m} 匹配前一个字符最少n次,最多m次
a{n,} 匹配前一个字符最少n次
a{n} 匹配前一个字符正好n次
a{,m} 匹配前一个字符最多m次
实践:
[root@buffes test]# egrep "0{3,4}" buffes.txt
my qq num is 1234567.
not 1234567.
[root@buffes test]# egrep "0{3,}" buffes.txt
my qq num is 1234567.
not 1234567.
[root@buffes test]# egrep "0{3}" buffes.txt
my qq num is 1234567.
not 1234567.
[root@buffes test]# egrep "0{,3}" buffes.txt
I am buffes teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
our site is http://www.buffes.cn
my qq num is 1234567.
not 1234567.
my god ,i am not buffes,but buffes!
:::
///
:d::f
/etc/buffes//
8. 扩展正则测试题
测试题:
1.过滤/etc/passwd中含有root或buffes的行。
grep -E "root|buffes" /etc/passwd
2.过滤/etc/passwd中至少含有1个0字符串的行。
egrep "0+" /etc/passwd
3.过滤/etc/passwd中匹配o字符0次或1次的行。
egrep "o?" /etc/passwd
4.过滤/etc/passwd中匹配0字符1次到3次的行。
egrep "0{1,3}" /etc/passwd
5.过滤/etc/shadow中匹配含有连续多个冒号或斜线的行。
egrep "[:/]+" /etc/shadow
9. 元字符
表达式 | 描述 |
---|---|
\b | 匹配单词边界,例如:\bbuffes\b只匹配buffes单词不匹配buffes* |
\B | 匹配非单词的边界例如:buffes\B 匹配buffes123中的buffes,不匹配单独的buffes单词 |
\w | 匹配字母、数字与下划线,等价[_[:alnum:]] |
\W | 匹配字母、数字与下划线以外的字符,等价[^_[:alnum:]] |
\d | 匹配单个数字字符,注意,这个表达式需要使用grep -P参数才能识别* |
\D | 匹配单个非数字字符,注意,这个表达式需要使用grep -P参数才能识别 |
\s | 匹配1位空白字符,注意,这个表达式需要使用grep -P参数才能识别 |
\S | 匹配1位非空白字符,注意,这个表达式需要使用grep -P参数才能识别 |
测试:
[root@buffes test]# egrep "buffes\b" /etc/passwd
buffes:x:5023:5023::/home/buffes:/bin/bash
[root@buffes test]#
[root@buffes test]# egrep "\bbuffes\b" /etc/passwd
buffes:x:5023:5023::/home/buffes:/bin/bash
[root@buffes test]# egrep -w "buffes" /etc/passwd
buffes:x:5023:5023::/home/buffes:/bin/bash
10. 特殊预定义表达式
正则表达式 | 描述 | 示例 |
---|---|---|
[:alnum:] | 匹配任意一个字母或数字字符,相当于[a-zA-Z0-9] | [[:alnum:]] |
[:alpha:] | 匹配任意一个大小写字母字符,相当于[a-zA-Z] | [[:alpha:]] |
[:blank:] | 空格与制表符(横向和纵向) | [[:blank:]] |
[:digit:] | 匹配任意一个数字字符,相当于[0-9] | [[:digit:]] |
[:lower:] | 匹配小写字母,相当于[a-z] | [[:lower:]] |
[:upper:] | 匹配大写字母,相当于[A-Z] | [[:upper:]] |
[:punct:] | 匹配标点符号 | [[:punct:]] |
[:space:] | 匹配一个包括换行符、回车等在内的所有空白符 | [[:space:]] |
[:graph:] | 匹配任何一个可以看得见的且可以打印的字符 | [[:graph:]] |
[:xdigit:] | 任何一个十六进制数(即:0-9,a-f,A-F) | [[:xdigit:]] |
[:cntrl:] | 任何一个控制字符(ASCII字符集中的前32个字符) | [[:cntrl:]] |
[:print:] | 任何一个可以打印的字符 | [[:print:]] |
[root@buffes test]# egrep "[[:alnum:]]" buffes.txt
I am buffes teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
our site is http://www.buffes.cn
my qq num is 1234567.
not 1234567.
my god ,i am not buffes,but buffes!
:d::f
/etc/buffes//
[root@buffes test]# egrep "[[:alpha:]]" buffes.txt
I am buffes teacher!
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
our site is http://www.buffes.cn
my qq num is 1234567.
not 1234567.
my god ,i am not buffes,but buffes!
:d::f
/etc/buffes//
[root@buffes test]# egrep "[:digit:]" buffes.txt
grep: character class syntax is [[:space:]], not [:space:]
[root@buffes test]# egrep "[[:digit:]]" buffes.txt
my qq num is 1234567.
not 1234567.
[root@buffes test]#
-A after 显示过滤的字符串和它之后的多少行
-B before 显示过滤的字符串和它之前的多少行
-C context 显示过滤的字符串和它之前之后的多少行
[root@buffes test]# grep -A 3 5 b.txt
5
6
7
8
[root@buffes test]# grep -B 3 5 b.txt
2
3
4
5
[root@buffes test]# grep -C 3 5 b.txt
2
3
4
5
6
7
8
二、Sed命令语法及参数说明
【功能说明】
Sed是Stream Editor(字符流编辑器)的缩写,简称流编辑器。
Sed是操作、过滤和转换文本内容的强大工具。常用功能有对文件实现快速增删改查(增加、删除、修改、查询),其中查询的功能中最常用的2大功能是过滤(过滤指定字符串)和取行(取出指定行)。
取行和替换
【语法格式】
sed [选项] [sed内置命令字符] [输入文件]
options[选项] 解释说明(带※的为重点)
-n 取消默认sed的输出,常与sed内置命令的p连用※
输出想要的内容。
-i 直接修改文件内容,而不是输出到终端。
-e 允许多次编辑
p 全拼print,表示打印匹配行的内容,通常p会与选项-n一起使用※
[root@buffes test]# cat -n buffes.txt
1 I am buffes teacher!
2 I teach linux.
3
4 I like badminton ball ,billiard ball and chinese chess!
5 our site is http://www.buffes.cn
6 my qq num is 1234567.
7
8 not 1234567.
9 my god ,i am not buffes,but buffes!
10 :::
11 ///
12 :d::f
13 /etc/buffes//
sed 命令的练习
取buffes.txt 2-4行
sed -n '2,4p' buffes.txt
[root@buffes test]# sed -n '2,4p' buffes.txt
I teach linux.
I like badminton ball ,billiard ball and chinese chess!
取第4行
[root@buffes test]# sed -n '4p' buffes.txt
I like badminton ball ,billiard ball and chinese chess!
笔试至少5个答案
问题2:过滤出含有buffes字符串的行※。
sed -n '//p' #框架化
方法1:
[root@oldboy test]# grep buffes buffes.txt
I am buffesteacher!
our site is http://www.buffes.cn
/etc/buffes//
方法2:
[root@buffes test]# sed -n '/buffes/p' buffes.txt
I am buffes teacher!
our site is http://www.buffes.cn
/etc/buffes//