扩展正则表达式
支持的工具:egrep
、awk
,注意:使用grep
要配合-E
或者-P
使用,sed
要配合-r
使用。
元字符 | 含义及用法 |
---|---|
+ |
匹配前面子表达式1次以上,例: go+d ,将匹配至少一个o ,如god 、good 、goood 等 |
? |
匹配前面子表达式0次或者1次,例: go?d ,将匹配gd 或god |
() |
将括号中的字符串作为一个整体,例1: g(oo)+d ,将匹配oo 整体1次以上,如good 、gooood 等 |
` | ` |
bash
[root@localhost ~]# grep -E go+d test.sh
god
good
goood
gooood
gooooood
gooooooodddd
oooogooood
[root@localhost ~]# grep -E go?d test.sh
gd
god
ooooogd
[root@localhost ~]# grep -E "g(oo)+d" test.sh
good
gooood
gooooood
oooogooood
[root@localhost ~]# grep -E "g(oa|ol)+d" test.sh
gold
goad
o{number}表示含有number个o的内容显示,o{number,}表示大于等于number的o的内容显示,
o{2,4}表示大于等于2小于等于4个o的内容显示
bash
[root@localhost ~]# vim test.sh
[root@localhost ~]# grep -E "go{2}d" test.sh
good
[root@localhost ~]# grep -E "go{2,}d" test.sh
good
goood
gooood
gooooood
gooooooodddd
oooogooood
[root@localhost ~]# grep -E "go{2,4}d" test.sh
good
goood
gooood
oooogooood
|------|-------------------------------|
| \w
| 匹配包括下划线的任何单词字符。 |
| \W
| 匹配任何非单词字符。等价于[^A-Za-z0-9_]
。 |
| \d
| 匹配一个数字字符。 |
| \D
| 匹配一个非数字字符。等价于[^0-9]
。 |
| \s
| 空白符。 |
| \S
| 非空白符。 |
bash
[root@localhost ~]# grep -P "\d" test.sh
abccba123
[root@localhost ~]# grep -P "\w" test.sh
gd
god
good
goood
gooood
goooabcd
gooooood
gooooooodddd
abccba
abccba123
oooogooood
ooooogd
gold
goad
[root@localhost ~]# grep -P "\W" test.sh
[root@localhost ~]# grep -P "\D" test.sh
gd
god
good
goood
gooood
goooabcd
gooooood
gooooooodddd
abccba
abccba123
oooogooood
ooooogd
gold
goad
[root@localhost ~]# grep -P "\s" test.sh
[root@localhost ~]# grep -P "\S" test.sh
gd
god
good
goood
gooood
goooabcd
gooooood
gooooooodddd
abccba
abccba123
oooogooood
ooooogd
gold
goad
下面用法类似"\S",但是"\S"只能除去整行的空格不能除去行内的空格,例如:123 assdl,"\S"不能除去空格。
bash
[root@localhost ~]# grep -v [[:space:]] test.sh
gd
god
good
goood
gooood
goooabcd
gooooood
gooooooodddd
abccba
abccba123
oooogooood
ooooogd
gold
goad
常见例题
电话例题
找出区号025开头的号码,且号码与区号间可以是空格、-、没有,号码必须是5或者8开头的八位数。
02588888888 025-5555555555 025 12345678 025 54321678 025ABC88888 025-85432109 028-85643210 0251-52765421
答案:
bash
[root@localhost ~]# grep -E "^(025)[ -]?[58][0-9]{7}$" phone_number.txt
02588888888
025 54321678
025-85432109
解题思路
(1)将电话号码分为三段,第一段找出区号025开头。^是以什么开头,用()将025作为一个整体
bash
^(025)
(2)第二段筛选出号码与区号之间的分隔符,号码与区间之间可以是空格、-、没有。将题目要求的空格和-写入[],由于?是前面的子表达式0次或1次,0次就符合题目要求的没有
bash
[ -]?
(3)第三段为号码后几位,必须是以5或者8开头的八位数。用[]确认是5或8数字开头的号码,然后再匹配0-9的7位数结尾的数
bash
[58][0-9]{7}$
电子邮箱例题
根据 用户名@子域名.[二级域名].顶级域
格式找出符合要求的电子邮箱
zhangsan123@qq.com li si@163.com wang@wu@sina.com zhao liu@126.com qianqi@sina.com.cn
答案:
bash
[root@localhost ~]# grep -E "^([a-zA-Z_][^@ ]{5,17})@[a-zA-Z0-9\_\-\.]+(\.[a-zA-Z0-9\_\-\.]+)?\.([a-zA-Z]{2,5})$" test.txt
zhangsan123@qq.com
qianqi@sina.com.cn
解题思路
将邮箱拆分为三段
(1)第一段用户名@:长度要求在6-18位,任意大小写英文,任意数字,出了@符号和空格以外的其他任意符号字符,开头只能是------或者字母
bash
^([a-zA-Z_][^@ ]{5,17})@
第二段子域名[二级域名]:长度任意,符号只能包含"-_."
bash
[a-zA-Z0-9\_\-\.]+(\.[a-zA-Z0-9\_\-\.]+)?
第三段为".顶级域名":长度位2-5,任意大小写英文。
bash
\.([a-zA-Z]{2,5})$
IP地址匹配例题
bash
[root@localhost ~]# grep -E "^((1[0-9{1,2}|2[0123456]{1,2})\.)((0|1[0-9]{1,2}|2[012345]{1,2})\.)+(0|1[0-9]{1,2}|2[012345]{1,2})$" ip.txt
192.168.222.122
sed编辑器
命令格式
sed -e '操作' 文件l 文件2 ...
sed -n -e '操作' 文件1 文件2 ...
sed -f 脚本文件 文件1 文件2 ...
sed -i -e '操作' 文件1 文件2 ...
sed -e 'n{ #n意为:指定行
操作l
操作2
...
}' 文件1 文件2 ...
常用选项
选项 | 含义 |
---|---|
-e 或--expression= |
表示用指定命令来处理输入的文本文件,只有一个操作命令时可省略,一般在执行多个操作命令使用。 |
-f 或--file= |
表示用指定的脚本文件来处理输入的文本文件。 |
-h 或--help |
显示帮助。 |
-n 、--quiet 或silent |
禁止sed编辑器输出,但可以与p 命令一起使用完成输出。 |
-i |
直接修改目标文本文件。 |
-r, --regexp-extended | 支持扩展正则表达式 |
常用操作
操作 | 含义 |
---|---|
s |
替换,替换指定字符。 |
d |
删除,删除选定的行。 |
a |
增加,在当前行下面增加一行指定内容。 |
i |
插入,在选定行上面插入一行指定内容。 |
c |
替换,将选定行替换为指定内容。 |
y |
字符转换,转换前后的字符长度必须相同。 |
p |
打印,如果同时指定行,表示打印指定行;如果不指定行,则表示打印所有内容,如果有非打印字符,则以ASCII码输出。其通常与-n 选项一起使用。 |
= |
打印行号。 |
l (小写L) |
打印数据流中的文本和不可打印的AscII字符(比如结束符$ 、制表符\t ) |
替换内容
替换标记
数字 |
表明新字符串将替换第几处匹配的地方 |
g |
表明新字符串将会替换所有匹配的地方 |
p |
打印与替换命令匹配的行,与-n一起使用 |
w 文件 |
将替换的结果写到文件中 |
awk编辑器
1.概念
sed命令常用于一整行的处理,而awk比较倾向于将一行分成多个"字段"然后再进行处理。awk信息的读入也是逐行读取的,执行结果可以通过print
的功能将字段数据打印显示。
在使用awk命令的过程中,可以使用逻辑操作符 &&
表示与、||
表示或、!
表示非;还可以进行简单的数学运算,如+
、-
、*
、/
、%
、^
分别表示加、减、乘、除、取余和乘方。
2.工作原理
逐行读取文本,默认以空格或tab键为分隔符进行分隔,将分隔所得的各个字段保存到内建变量中,并按模式或者条件执行编辑命令。
3.用法
常见的内建变量
内建变量 | 含义 |
---|---|
FS |
列分割符。指定每行文本的字段分隔符,默认为空格或制表位。与-F 作用相同。 |
NF |
当前处理的行的字段个数。$NF 代表最后一个字段。 |
NR |
当前处理的行的行号(序数)。 |
$0 |
当前处理的行的整行内容。 |
$n |
当前处理行的第n个字段(第n列)。 |
FILENAME |
被处理的文件名。 |
RS |
行分隔符。awk从文件上读取资料时,将根据Rs的定义把资料切割成许多条记录,而awk比较倾向于将一行分成多个一次仅读入一条记录,以进行处理。预设值是\n 。 |
基本用法以及NF的作用 。
bash
[root@localhost ~]# cat /etc/passwd | awk -F : '/ftp/{print $1}'
ftp
[root@localhost ~]# cat /etc/passwd | awk -F : '/ftp/{print $NF}'
/usr/sbin/nologin
[root@localhost ~]# cat /etc/passwd | awk -F : '/ftp/{print $(NF-1)}'
/var/ftp
[root@localhost ~]# cat /etc/passwd | awk -F : '/ftp/{print $(NF-2)}'
FTP User
[root@localhost ~]# cat /etc/passwd | awk -F : '/ftp/{print $(NF-3)}'
50
计算物理内置使用百分比和剩余内存百分比
bash
[root@localhost ~]# cat /proc/meminfo | awk '/MemTotal|MemFree|MemAvailable/ {count++; val[count]=$2} END {print val[2]/val[1]*100"%"; print val[3]/val[1]*100"%"}'
73.1579%
81.7701%
[root@localhost ~]# cat /proc/meminfo | awk '/MemTotal|MemFree|MemAvailable/ {val[NR-1]=$2} END {print val[1]/val[0]*100"%"; print val[2]/val[0]*100"%"}'
73.0983%
81.7133%
[root@localhost ~]# cat /proc/meminfo | awk '/MemTotal|MemFree|MemAvailable/ {val[i++]=$2} END {print val[1]/val[0]*100"%"; print val[2]/val[0]*100"%"}'
73.1657%
81.7821%