今天继续昨天的正则表达式进行学习
扩展正则表达式
支持的工具: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 等 |
| | 以或的方式匹配字符串,例:g(oo|la)d ,将匹配good 或者 glad |
[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的内容显示
[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 | 非空白符。 |
[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
abccbaabccba123
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”不能除去空格。
[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
答案:
[root@localhost ~]# grep -E "^(025)[ -]?[58][0-9]{7}$" phone_number.txt
02588888888
025 54321678
025-85432109
解题思路
(1)将电话号码分为三段,第一段找出区号025开头。^是以什么开头,用()将025作为一个整体
^(025)
(2)第二段筛选出号码与区号之间的分隔符,号码与区间之间可以是空格、-、没有。将题目要求的空格和-写入[],由于?是前面的子表达式0次或1次,0次就符合题目要求的没有
[ -]?
(3)第三段为号码后几位,必须是以5或者8开头的八位数。用[]确认是5或8数字开头的号码,然后再匹配0-9的7位数结尾的数
[58][0-9]{7}$
电子邮箱例题
根据 用户名@子域名.[二级域名].顶级域
格式找出符合要求的电子邮箱
zhangsan123@qq.com li si@163.com wang@wu@sina.com zhao liu@126.com qianqi@sina.com.cn
答案:
[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位,任意大小写英文,任意数字,出了@符号和空格以外的其他任意符号字符,开头只能是——或者字母
^([a-zA-Z_][^@ ]{5,17})@
第二段子域名[二级域名]:长度任意,符号只能包含"-_."
[a-zA-Z0-9\_\-\.]+(\.[a-zA-Z0-9\_\-\.]+)?
第三段为“.顶级域名”:长度位2-5,任意大小写英文。
\.([a-zA-Z]{2,5})$
IP地址匹配例题
[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的作用 。
[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
计算物理内置使用百分比和剩余内存百分比
[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%