正则表达式
用法
REGEXP: Regular Expressions,由一类特殊字符及文本字符所编写的模式,其中有些字符(元字符)不表示字符字面意义,而表示控制或通配的功能,类似于增强版的通配符功能,但与通配符不同,通配符功能是用来处理文件名,而正则表达式是处理文本内容中字符。
正则表达式被很多程序和开发语言所广泛支持:vim, less,grep,sed,awk, nginx,mysql 等
正则表达式:主要用来匹配字符串(命令结果,文本内容)
通配符:匹配文件(而且是已存在的文件),一般与find一起使用
- 基本正则表达式
- 扩展正则表达式
可以使用
man 7 regex
可以使用 man手册帮助
元字符(字符匹配)
元字符:
注册用户 数字字母组成 20字符
[0-9a-zA-Z]次数
单个字符出现的次数
echo ”用户名“ | grep [0-9a-zA-Z]次数 (20个及以下)
元字符 | 含义 |
. | 匹配任意单个字符,可以是一个汉字 |
[] | 匹配指定范围内的任意单个字符,示例:[zhou],[0-9],[],[a-zA-Z],[[:alpha:]],[0-9a-zA-Z]= [:alnum:] |
[^] | 匹配指定范围外的任意单个字符,示例:[^zhou] [^a.z] [a.z] |
[:alnum:] | 字母和数字 |
[:alpha:] | 代表任何英文大小写字符,亦即 A-Z, a-z |
[:lower:] | 小写字母,示例:[[:lower:]],相当于[a-z] |
[:upper:] | 大写字母 |
[:blank:] | 空白字符(空格和制表符) |
[:space:] | 包括空格、制表符 (水平和垂直)、换行符、回车符等各种类型的空白,比[:blank:]包含的范围广 |
[:cntrl:] | 不可打印的控制字符(退格、删除、警铃...) |
[:digit:] | 十进制数字 |
[:xdigit:] | 十六进制数字 |
[:graph:] | 可打印的非空白字符 |
[:print:] | 可打印字符 |
[:punct:] | 标点符号 |
\w | #匹配单词构成部分,等价于[_[:alnum:]] |
\W | #匹配非单词构成部分,等价于[^_[:alnum:]] |
\S | #匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 |
\s | #匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。 |
注意Unicode 正则表达式会匹配全角空格符
r..t ..代表任意两字符
区分正则表达式和通配符的区别
表示次数
元字符 | 功能 |
* | #匹配前面的字符任意次,包括0次,贪婪模式:尽可能长的匹配 |
.* | #任意长度的任意字符 不包括0次 |
\? | #匹配其前面的字符出现0次或1次,即:可有可无 |
\+ | #匹配其前面的字符出现最少1次,即:肯定有且 >=1 次 |
\{n\} | #匹配前面的字符n次 |
\{m,n\} | #匹配前面的字符至少m次,至多n次 |
\{,n\} | #匹配前面的字符至多n次,<=n |
\{n,\} | #匹配前面的字符至少n次 |
[root@host1:/data# ]echo good |grep 'go\{2\}d'
good 表示匹配o两次
[root@host1:/data# ]echo goooood |grep 'go\{2,\}d'
goooood 表示匹配o两次以上
[root@host1:/data# ]echo goooood |grep 'go\{2,5\}d'
goooood 表示匹配o,2到5次
[root@host1:/data# ]echo gooooood |grep 'go\{2,5\}d'
表示6个o匹配失败
[root@host1:/data# ]echo gd |grep 'go*d'
gd
[root@host1:/data# ]echo ggggd |grep 'go*d'
ggggd 表示匹配0次或多次,就算没有o也可以匹配
[root@host1:/data# ]echo gadqwdgkjld |grep "g.*d"
gadqwdgkjld 表示g和d之间任意字符都可以匹配, .* 表示多个任意字符
[root@host1:/data# ]echo god |grep "go\?d"
god
[root@host1:/data# ]echo good |grep "go\?d"
good 表示o出现的0或1次都可以匹配,所有god和good都可以匹配
[root@host1:/data# ]echo good |grep "go\+d"
good
[root@host1:/data# ]echo god |grep "go\+d"
god
[root@host1:/data# ]echo gd |grep "go\+d"
表示o出现1次以上才能匹配到,所以gd不能匹配
表示位置锚定
^ | #行首锚定, 用于模式的最左侧 |
$ | #行尾锚定,用于模式的最右侧 |
^PATTERN$ | #用于模式匹配整行 (单独一行 只有root) |
^$ | #空行 |
^[[:space:]]*$ | # 空白行 tab 换行 回车 |
\< 或 \b | #词首锚定,用于单词模式的左侧(连续的数字,字母,下划线都算单词内部) |
\> 或 \b | #词尾锚定,用于单词模式的右侧 |
\<PATTERN\> | #匹配整个单词 |
分组或其他
分组:( ) 将多个字符捆绑在一起,当作一个整体处理,如:(root)+
后向引用:分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名
方式为: \1, \2, \3, ... 分组
\1 表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符
扩展正则表达式(表示字符相差不大)
grep -E
egrep 默认使用的 是扩张正则
表示次数
* | 匹配前面字符任意次 |
? | 0或1次 |
+ | 1次或多次 |
{n} | 匹配n次 |
{m,n} | 至少m,至多n次 |
{,n} | #匹配前面的字符至多n次,<=n,n可以为0 |
{n,} | #匹配前面的字符至少n次,<=n,n可以为0 |
表示分组
() 分组
分组:() 将多个字符捆绑在一起,当作一个整体处理,如:\(root\)+
后向引用:\1, \2, ...
| 或者
a|b #a或b
C|cat #C或cat
(C|c)at #Cat或cat
数字字母@数字字母.数字字母
[[:alnum:]]+@ [[:alnum:]]+\.[[:alnum:]]+
1.表示QQ号
2.表示邮箱
3.表示手机号
grep
选项:
-color=auto #对匹配到的文本着色显示
-m # 匹配#次后停止 匹配到 #行停止
grep -m 1 root /etc/passwd #多个匹配只取第一个
-v 显示不被pattern匹配到的行,即取反
grep -Ev '^[[:space:]]*#|^$' /etc/fstab
-i 忽略字符大小写
-n 显示匹配的行号
-c 统计匹配的行数
-o 仅显示匹配到的字符串
-q 静默模式,不输出任何信息 写脚本
-A # after, 后#行
-B # before, 前#行
-A 3 -B 3查看上下三行
-C # context, 前后各#行
-e 实现多个选项间的逻辑or关系
grep -e root -e bash /etc/passwd #包含root或者包含bash 的行
-w 匹配整个单词
r..t ..可以代表任意字符
-E 使用ERE,相当于egrep
-F 不支持正则表达式,相当于fgrep
-f file 根据模式文件,处理两个文件相同内容 把第一个文件作为匹配条件 grep -f a b
-r 递归目录,但不处理软链接 开始搜索目录
-R 递归目录,但处理软链接
sed
Sed是从文件或管道中读取一行,处理一行,输出一行;再读取一行,再处理一行,再输出一行,直到最后一行。每当处理一行时,把当前处理的行存储在临时缓冲区中,称为模式空间(PatternSpace),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。一次处理一行的设计模式使得sed性能很高,sed在读取大文件时不会出现卡顿的现象。如果使用vi命令打开几十M上百M的文件,明显会出现有卡顿的现象,这是因为vi命令打开文件是一次性将文件加载到内存,然后再打开。Sed就避免了这种情况,一行一行的处理,打开速度非常快,执行速度也很快
基本用法
sed [option]... 'script;script;...' [input file...]
选项 自身脚本语法 支持标准输入管道
常用选项:
选项
功能
-n
不输出模式空间内容到屏幕,即不自动打印
-e
多点编辑sed -n -e '/^r/p' -e'/^b/p' /etc/passwd
-f FILE
从指定文件中读取编辑脚本
-r, -E
使用扩展正则表达式
-i.bak
备份文件并原处编辑
#说明:
-ir 不支持
-i -r 支持
-ri 支持
-ni 会清空文件
sed脚本格式
单引号中间需要写脚本;脚本格式如下
'地址+命令'组成
1. 不给地址:对全文进行处理(比如行号)
2. 单地址:
#:指定的行,$:最后一行
/pattern/:被此处模式所能够匹配到的每一行,正则表达式
3. 地址范围:
#,# #从#行到第#行,3,6 从第3行到第6行
#,+# #从#行到+#行,3,+4 表示从3行到第7行
/pat1/,/pat2/ 第一个正则表达式 到 第二个正则表达式之间的行
#,/pat/ 从#号行为开始找到 pat为止 3 , /^r/
/pat/,# 找到#号个pat为止
4. 步进:~
1~2 奇数行
2~2 偶数行
sed -n 'n;p' testfile1 #打印偶数行
sed -n '2,${n;p}' testfile1
脚本命令
p 打印当前模式空间内容,追加到默认输出之后
Ip 忽略大小写输出
d 删除模式空间匹配的行,并立即启用下一轮循环
a [\]text 在指定行后面追加文本,支持使用\n实现多行追加
i [\]text 在行前面插入文本
c [\]text 替换行为单行或多行文本
w file 保存模式匹配的行至指定文件 seq 10 |sed -n '2wa.txt'
r file 读取指定文件的文本至模式空间中匹配到的行后 seq 10|sed '2r /etc/issue'
= 为模式空间中的行打印行号 sed '2=' /etc/passwd sed -n -e '=;p' /etc/passwd
! 模式空间中匹配行取反处理seq 10 |sed -n '1~2!p'
q 结束或退出sed seq 10 | sed '3q'
搜索替代
s/pattern/string/修饰符 查找替换,支持使用其它分隔符,可以是其它形式:s@@@,s###
替换修饰符:
g 行内全局替换
p 显示替换成功的行
w /PATH/FILE 将替换成功的行保存至文件中
I,i 忽略大小写
awk命令
awk:Aho, Weinberger, Kernighan,报告生成器,格式化文本输出,GNU/Linux发布的AWK目前由自由软件基金会(FSF)进行开发和维护,通常也称它为 GNU AWK
有多种版本:
- AWK:原先来源于 AT & T 实验室的的AWK
- NAWK:New awk,AT & T 实验室的AWK的升级版
- GAWK:即GNU AWK。所有的GNU/Linux发布版都自带GAWK,它与AWK和NAWK完全兼容
GNU AWK 用户手册文档
gawk:模式扫描和处理语言,可以实现下面功能
vim: 是将整个文件加载到内存中 再进行编辑, 受限你的内存
awk(语言): 读取一行处理一行,
在 Linux/UNIX 系统中,awk 是一个功能强大的编辑工具,逐行读取输入文本,默认以空格或tab键作为分隔符作为分隔,并按模式或者条件执行编辑命令。而awk比较倾向于将一行分成<font color='red'>多个字段</font>然后进行处理。AWK信息的读入也是逐行
指定的匹配模式进行查找,对符合条件的内容进行格式化输出或者过滤处理,可以在无交互
的情况下实现相当复杂的文本操作,被广泛应用于 Shell 脚本,完成各种自动化配置任务。
工作原理:
前面提到 sed 命令常用于一整行的处理,而 awk 比较倾向于将一行分成多个“字段”然后再进行处理,且默认情况下字段的分隔符为空格或 tab 键。awk 执行结果可以通过 print 的功能将字段数据打印显示。
格式:
awk [options] 'program' var=value file…
说明:
program通常是被放在单引号中,并可以由三种部分组成
- BEGIN语句块
- 模式匹配的通用语句块
- END语句块
常见选项:
- -F “分隔符” 指明输入时用到的字段分隔符,默认的分隔符是若干个连续空白符
- -v var=value 变量赋值
Program格式:
pattern{action statements;..}
- pattern:决定动作语句何时触发及触发事件,比如:BEGIN,END,正则表达式等
- action statements:对数据进行处理,放在{}内指明,常见:print, printf
output statements:print,printf
Expressions:算术,比较表达式等
Compound statements:组合语句
Control statements:if, while等
input statements
第一步:执行BEGIN{action;… }语句块中的语句
第二步:从文件或标准输入(stdin)读取一行,然后执行pattern{ action;… }语句块,它逐行扫描文件,
从第一行到最后一行重复这个过程,直到文件全部被读取完毕。
第三步:当读至输入流末尾时,执行END{action;…}语句块
BEGIN语句块在awk开始从输入流中读取行之前被执行,这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中
END语句块在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是一个可选语句块
pattern语句块中的通用命令是最重要的部分,也是可选的。如果没有提供pattern语句块,则默认执行{ print },即打印每一个读取到的行,awk读取的每一行都会执行该语句块
基础用法
awk 'patterm{action}'
BEGIN{}模式表示,在处理指定的文本前,需要先执行BEGIN模式中的指定动作; awk再处理指定的文本,之后再执行END模式中的指定动作,END{}语句中,一般会放入打印结果等语句。
提取磁盘的分区利用率
df|awk '{print $5}'
df|awk -F"( +|%)" '{print $5}' ##一次性提取出,不要百分号
df |awk -F"[[:space:]]+|%" '{print $5}'
df |awk -F"[ %]+" '{print $5}'
awk 常见的内置变量
awk 选项 '模式{print }'
FS :指定每行文本的字段分隔符,缺省默认为空格或制表符(tab)。与 “-F”作用相同 -v "FS=:"
OFS:输出时的分隔符
NF:当前处理的行的字段个数
NR:当前处理的行的行号(序数)
$0:当前处理的行的整行内容
$n:当前处理行的第n个字段(第n列)
FILENAME:被处理的文件名
RS:行分隔符。awk从文件上读取资料时,将根据RS的定义就把资料切割成许多条记录,而awk一次仅读入一条记录进行处理。预设值是\n
FS输入分隔符
awk -v FS=':' '{print $1FS$3}' /etc/passwd
此处FS 相当于于变量 -v 变量赋值 相当于 指定: 为分隔符
awk -F: '{print $1":"$3}' /etc/passwd
OFS输出分隔符
awk -v FS=':' -v OFS='==' '{print $1,$3}'
RS行分隔符
NF
[root@host1:/data# ]df
文件系统 1K-块 已用 可用 已用% 挂载点
/dev/mapper/centos-root 40137576 5882896 34254680 15% /
devtmpfs 917600 0 917600 0% /dev
tmpfs 933524 0 933524 0% /dev/shm
tmpfs 933524 9240 924284 1% /run
tmpfs 933524 0 933524 0% /sys/fs/cgroup
/dev/sda1 1038336 182396 855940 18% /boot
/dev/mapper/centos-home 19593216 36952 19556264 1% /home
tmpfs 186708 12 186696 1% /run/user/42
tmpfs 186708 0 186708 0% /run/user/0
[root@host1:/data# ]df |awk '{print NF}' NF代表字段的个数
6
6
6
6
6
6
6
6
6
6
[root@host1:/data# ]df |awk '{print $NF}' 打印第六列
挂载点
/
/dev
/dev/shm
/run
/sys/fs/cgroup
/boot
/home
/run/user/42
/run/user/0
[root@host1:/data# ]df |awk '{print $(NF-1)}' 打印第五列
已用%
15%
0%
0%
1%
0%
18%
1%
1%
0%
NR
表示打印的时候在每行前面加上行号
[root@host1:/data# ]awk 'NR==2{print NR,$1}' /etc/passwd //只取第二行的第一个字段
2 bin:x:1:1:bin:/bin:/sbin/nologin
[root@host1:/data# ]awk 'NR==1,NR==3{print NR,$0}' passwd //打印出1到3 行
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@host1:/data# ]awk 'NR==1||NR==3{print NR,$0}' passwd //打印出1和3行
1 root:x:0:0:root:/root:/bin/bash
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
打印出函数取余数为0行
打印出函数取余数为1的行
自定义变量
awk -v 自定义变量 'program' [文件名]
printf
%s:显示字符串
%d, %i:显示十进制整数
%f:显示为浮点数
%e, %E:显示科学计数法数值
%c:显示字符的ASCII码
%g, %G:以科学计数法或浮点形式显示数值
%u:无符号整数
%%:显示%自身
模式PATTERN
awk '模式{处理动作}'
PATTERN:根据pattern条件,过滤匹配的行,再做处理
模式为空
如果模式为空表示每一行都匹配成功,相当于没有额外条件
awk -F: '{print $1,$3}' /etc/passwd
正则匹配
/regular expression/:仅处理能够模式匹配到的行,需要用/ /括起来
例子:
awk '/^UUID/{print $1}' /etc/fstab
line ranges:行范围
不支持使用行号,但是可以使用变量NR 间接指定行号加上比较操作符 或者逻辑关系
算术操作符
x+y, x-y, x*y, x/y, x^y, x%y
-x:转换为负数
+x:将字符串转换为数值
比较操作符:
==, !=, >, >=, <, <=
#####逻辑
与:&&,并且关系
或:||,或者关系
非:!,取反
模式匹配符:
~ 左边是否和右边匹配,包含关系
!~ 是否不匹配
BEGIN END
BEGIN{}:仅在开始处理文件中的文本之前执行一次
END{}:仅在文本处理完成之后执行一次
awk 'BEGIN{...};{...};END{...}' 文件 #处理过程:
1、在awk处理指定的文本之前,需要先执行BEGIN{...}模式里的命令操作;
2、中间的{...} 是真正用于处理文件的命令操作;
3、在awk处理完文件后才会执行END{…}模式里的命令操作。END{ }语句块中,往往会放入打印结果等语句。
关系表达式(扩展)
关系表达式结果为“真”才会被处理
真:结果为非0值,非空字符串
假:结果为空字符串或0值
seq 10 |awk 'n++' 打印除了第一行
seq 10 |awk '!n++' 只打第一行
seq 10 |awk '!0'
seq 10 |awk 'i=!i' 奇数行
seq 10 |awk -v i=1 'i=!i' 偶数行
seq 10 |awk '!(i=!i)' 偶数行
条件判断 (扩展)
awk 选项 '模式 {actions}'
条件判断写在 actions里
if(condition){statement;…}[else statement]
if(condition1){statement1}else if(condition2){statement2}else
if(condition3){statement3}...... else {statementN}
condition1:条件
statement1:语句
if语句:awk的if语句也分为单分支、双分支和多分支
单分支为if(判断条件){执行语句}
双分支为if(判断条件){执行语句}else{执行语句}
多分支为if(判断条件){执行语句}else if(判断条件){执行语句}else if(判断条件){执行语句}else if(判断条件){执行语句
awk中的for循环
for(expr1;expr2;expr3) {statement;…}
for(variable assignment;condition;iteration process) {for-body}
for(var in array) {for-body}
数组 (awk 数组来计算 )
awk数组特性:
- awk的数组是关联数组(即key/value方式的hash数据结构),索引下标可为数值(甚至是负数、小数等),也可为字符串 1. 在内部,awk数组的索引全都是字符串,即使是数值索引在使用时内部也会转换成字符串 2. awk的数组元素的顺序和元素插入时的顺序很可能是不相同的
- awk数组支持数组的数组