正则表达式

1.1 什么是正则表达式

  • 匹配一些有规律的东西,比如手机号丶日志文件等
  • 正则表达式regular expression (RE)
  • 正则使用:使用一些符号表达重复出现大小写,开头/结尾含义

1.2 应用场景

正则表达式 Linux三剑客使用,或者一些开发语言(python,golang...)
应用场景 过滤有规律的内容,尤其是日志

1.3 正则使用事项

  • 所有的符号英文符号
  • 学习正则,是通过grep命令学习 grep加上单引号 如 grep ‘xxx’
  • 注意系统的字符集;en_US.UTF-8 ,如果字符集出现问题修改成C(export LANG=c)
  • 快速掌握正则:配合grep -o参数学习

1.4 正则符号

分类 命令
基础正则 ^ $ ^$ . . \ grep/sed/awk
扩展正则 + | () {} ? egrep/sed-r/awk

1.5 正则vs通配符

分类 用途 支持的命令
正则(RE) 三剑客,高级语言,进行过滤 三剑客grep丶awk丶sed丶find
通配符(pathname extenslon 或glob) 匹配文件(文件名).txt .log {1..10} Linux下面的大部分命令

1.6基础正则

1)^

作用:表示以什么开始...的行
例:
搜素文件txt中以a开头的行
grep '^a'  [文件名(txt)]
注:如果没有任何提示,则表示要么字符有问题或者没有已a开头的行

2)$

作用:表示已什么..结尾
例:
搜素文件txt中以a结尾的行
grep 'a$'  [文件名(txt)]
注:搜素结尾$得在后面

3)^$

作用:表示搜素空行
空行这一行中没有任何内容(空格也是符号)
例:
搜素文件txt中的空行
grep '^$'  [文件名(txt)]
-v:反向抓取,也可用于排除(我想搜索123,加-v的话就是除了123显示 其他都显示)

4).

表示任意一个字符(.不匹配空行)

5)\转义字符

作用:表示去除原本特殊含义
例;
搜素文件txt.(点)结尾的行
[root@hadoop100 ~]# grep '.$' txt 
ifgdsfgd
sdfsss.
trete.g
gdfgd
eryer
str.
srtgrt
trtg
dfsfds.d
注;如果以.$正则来搜索的话,结果是任意一个字符结尾的行
[root@hadoop100 ~]# grep '\.$' txt 
sdfsss.
str.
加上\转义符后,就去除了.(点)原本的匹配任意字符的含义
  • 转义字符序列(部分)

    • \n 表示回车换行
    • \t 表示tab键

6)*

作用:*(星号)前一个字符匹配连续出现0次或者次以上
例:
[root@hadoop100 ~]# grep 's*' txt 
ifgdsfgd
sdfsss.
trete.g

gdfgd
eryer
str.

srtgrt
trtg
dfsfds.d
注:刚开始*比较少单独用,熟练掌握正则后

7).*

作用:在正则表达式里面表示所有内容, 任何内容,任意内容
整体记忆:.*表示所有即可
拆分: .(点)任意一个字符+ *前一个字符出现0次或者0次以上,加起来就表示所有了
  • 扩展
    • 匹配以s开头到的任意结尾行
    • [root@hadoop100 ~]# grep '^s.*' txt
      sdfsss.
      str.
      srtgrt
      sdadwaet
    • 匹配以s开头t结尾的行,中间任意内容
    • [root@hadoop100 ~]# grep '^s.*t' txt
      str.
      srtgrt
      sdadwaet
    • 正则特色
    • 正则表达式得到贪婪行,.表示所有或 连续出现的时候,会尽可能的过度匹配

8) [] 中括号

[abc] 1次匹配1个字符,匹配任何一个字符[a或b或c]
[]里面的内容去掉特殊意义,比如.在括号里面就是普通点
例;
[root@hadoop100 ~]# cat txt 
ifgdsfgd
sdfsss.
trete.g

gdfgd
eryer
str.

srtgrt
trtg
dfsfds.d
sdadwaet
[root@hadoop100 ~]# grep '[abc]' txt 
sdadwaet
注:通常如果匹配多个字符的情况下可以用什么到什么来写
如:匹配a到z的行
[root@hadoop100 ~]# grep '[a-z]' txt 
ifgdsfgd
sdfsss.
trete.g
gdfgd
eryer
str.
srtgrt
trtg
dfsfds.d
sdadwaet

如何匹配多个不同字符
例;匹配txt文件中的大写和数字
[root@hadoop100 ~]# grep '[A-Z0-9]' txt 
AdwsXfs
F
 oDSADSA
543DASA
注:大小写可以简写成a-Z

9)[^]

作用:取反丶排除
例:
grep '[^abc]' txt
表示:从txt中标记所有的包含abc的词,输出剩下行

10)总结

基础正则 含义 搭配
^ 以....开头的行
$ 以....结尾的行
^$ 表示空行 搭配固定
. 任意一个字符
* 前一个字符连续出现0次或者0次以上
.* 表示所有内容 搭配
\ 转义符字符,、\n \t
正则贪婪性 .*的时候或者是连续出现 一般与+号搭配
[] 一个整体,匹配里面任意一个字符
[^] 取反,排除,也是一个整体

1.7扩展正则

符号
+
|
()
{}

1)+ 前一个字符出现1次或者1次以上

注:grep不支持扩展正则,得用egrep
[root@hadoop102 ~]# grep '6+' txt 
[root@hadoop102 ~]# egrep '6+' txt 
434666666
34235435643
#或者在+前面加上转义字符\
[root@hadoop102 ~]# grep '6\+' txt 
434666666
34235435643
  • 匹配出连续出现的数字
[root@hadoop102 ~]# egrep '[0-9]+' txt 
434666666
34235435643
5e5y
e5745y
# -o;只输出匹配的内容
[root@hadoop102 ~]# egrep -o '[0-9]+' txt 
434666666
34235435643
5
5
5745

2)| 或者

#同中括号大同小异,中括号解决不了就可以用 | 
[root@hadoop102 ~]# cat txt 
sdfsdfs
sdfsdfs
ddddghggrr
cxgrsg
434666666
dtsfgdrge
34235435643

etrtgr
5e5y
y
e5745y
rtd:wq
[root@hadoop102 ~]# egrep 'e|4' txt 
434666666
dtsfgdrge
34235435643
etrtgr
5e5y
e5745y
符号 含义 应用场景
[] 1次匹配一个字符 匹配单个字符[] 和+
| 匹配1个字符或者多个字符 匹配单词的时候

3) () 被括起来的内容,表示一个整体 反向引用(一般用于sed)

  • 被括起来的内容,表示一个整体
  • 反向引用(一般用于sed)

4) {} 连续出现 o{n,m} 前一个字母o最少连续出现n次,最多出现m次

符号
o{n,m} 前一个字母o最少连续出现n次,最多出现m次
o{n} 前一个字母o连续出现n次

image-20230706173038609

5) ? 前一个字符出现0次或者1次

image-20230706173011342

6) 扩展正则总结

符号 含义 搭配
+ 前一个字符出现1次或者1次以上 []+
| 或者
[] 一个整体,sed反向引用
{} 前一个字母o最少连续出现n次,最多出现m次
? 前一个字符出现0次或者1次

2.1三剑客

三剑客的特点及应用

命令 特点 应用
grep 过滤丶查找 grep过滤的速度是最快的
sed 替换,修改文件内容丶取 行 如果要替换/修改文件内容,取出某个范围的值
awk 取列,统计计算 取列丶对比比较丶统计计算

grep

选项 含义
-E =egrep
-A 例:-A5 匹配你要的内容显示下接来的5行
-B 例:-B5 匹配你要的内容显示接上面的5行
-C 例:-C 5 匹配你要的内容显示上下面的5行
-c 统计出现了多少次行,同wc -l
-v 取反丶排除(行)
-n 显示行号
-i 忽略大小写
-w 匹配单词

-o 精确过滤

image-20230706173101042

sed

字符串替换

语法:sed 's/原字符串/替换字符串/' [文件路径]
#注意:
#若存在特殊字符,需要使用反斜线\进行转义;
#若存在单引号,外层的单引号改成双引号 sed "s/原字符串/替换字符串/"
#删除某一个字符串可写为:sed 's/原字符串//g'
替换所有匹配到的关键字:
sed 's/原字符串/替换字符串/g'
# 在末尾加g替换每一个匹配的关键字,否则只替换每行的第一个
#替换文件整行内容:
例:把unr第四行替换成www.baidu
[root@hadoop102 ~]#sed -i '4c\www.baidu' unr   
选项  功能
-e  直接在命令行模式上进行sed动作编辑,此为默认选项
-f  将sed的动作写在一个文件内,用–f filename 执行filename内的sed动作
-i  直接修改文件内容
-n  只打印模式匹配的行
-r  支持扩展正则表达式
-h --help   显示帮助
-v --version    显示版本信息
#命令:
a\  在当前行下面插入文本
i\  在当前行上面插入文本
c\  把选定的行改为新的文本
d   删除,删除选择的行
D   删除模板块的第一行
s   替换指定字符
h   拷贝模板块的内容到内存中的缓冲区
H   追加模板块的内容到内存中的缓冲区
g   获得内存缓冲区的内容,并替代当前模板块中的文本
G   获得内存缓冲区的内容,并追加到当前模板块文本的后面
l   列表不能打印字符的清单
n   读取下一个输入行,用下一个命令处理新的行而不是用第一个命令
N   追加下一个输入行到模板块后面并在二者间嵌入一个新行,改变当前行号码
p   打印模板块的行
P   打印模板块的第一行
q   退出Sed
b   lable 分支到脚本中带有标记的地方,如果分支不存在则分支到脚本的末尾
r   file 从file中读行
t   label if分支,从最后一行开始,条件一旦满足或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾
T   label 错误分支,从最后一行开始,一旦发生错误或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾
w   file 写并追加模板块到file末尾
W   file 写并追加模板块的第一行到file末尾
!   表示后面的命令对所有没有被选定的行发生作用
=   打印当前行号
#   把注释扩展到下一个换行符以前
#sed 替换标记 (s 替换脚本命令)
标记  作用
n   1~512 之间的数字,表示指定要替换的字符串出现第几次时才进行替换,例如,一行中有 3 个 A,但用户只想替换第二个 A,这时就用到这个标记
g   行内全局替换,如果没有 g,则只会在第一次匹配成功时做替换操作。例如,一行数据中有 3 个 A,则只会替换第一个 A
p   会打印与替换命令中指定的模式匹配的行。此标记通常与 -n 选项一起使用
w   将缓冲区中的内容写到指定的 file 文件中
x   互换模板块中的文本和缓冲区中的文本
y   把一个字符翻译为另外的字符(但是不用于正则表达式)
\n  匹配第n个子串,该子串之前在pattern中用 () 指定
&   已匹配字符串标记,用正则表达式匹配的内容进行替换
\   转义(转义替换部分包含:&、\ 等)
  • 特点及格式
    • sed stram edior 流编辑器,sed把处理的内容(文件)当作是水,源源不断的进行处理,直到文件末尾
    • sed格式
命令 选项 (s)sed命令功能(g)修饰符
sed -r 's#oldboy#oldgirl#g'
  • sed命令核心功能
功能
s 替换(substitute) sub
P 显示
d delete
cai 增加

3) sed查找

选项:

-n:按行号查找,搭配p使用 例:sed -n ‘5p’ jiujiu.txt 注:如果不加-n,则原文输出并重复输出指定行一遍-e 多重编辑,且命令顺序会影响结果
-f 指定一个 sed 脚本文件到命令行执行,
-r Sed 使用扩展正则
-i 直接修改文档读取的内容,不在屏幕上输出

命令 效果
p 行号的意思
d 删除(不加-选项 )
查找格式
'2p' 指定行号查找
'1,5p' 指定行号范围查找
'/xxxx/p' 类似于‘grep’过滤,//里面可以写正则 例:sed -n '/^s/p' jiujiu.txt
'/10:00/,/11:00/p' 表示范围的过滤,如果结尾范围输错,则从哪里开始查找输出到结尾

4)删除 d

删除格式
'2d' 指定行号删除
'1,5d' 指定行号范围删除
'/xxxx/' 类似于‘grep’过滤,//里面可以写正则 例:sed -n '/^s/d' jiujiu.txt
'/10:00/,/11:00/p' 表示范围的过滤,如果结尾范围输错,则从哪里开始删除输出到结尾
注:d是删除一行 常用:例sed '5d' jiujiu.txt

案例:删除文件中得到空行和包含#的行

egrep -v '^$|#' /etc/ssh/sshd_config
sed -r '/^$|#/d' /etc/ssh/sshd_config

# !的妙用
在sed和awk中表示取反
sed -nr '/^$|#/!p' /etc/ssh/sshd_config  #!p表示不显示空行/包含#号的行    

5)增加 :cai

命令 含义
c (replace)替代 替换这行的内容
a (append)追加 *重点 向指定的行或每一行追加内容 (相当于>>)【行的末尾追加】
i (insert)插入 向指定的行或每一行插入内容 (行的前面插入)

例:

#在txt中第四行下面追加一句jiujiu
[root@hadoop100 ~]# sed '4a jiujiu' txt 
#在txt中第四行上面追加一句jiujiu
[root@hadoop100 ~]# sed '4i jiujiu' txt
#把txt中第四行删除并改为jiujiu
[root@hadoop100 ~]# sed '4c jiujiu' txt

试题:

向config文件中追加多行内容

#需追加内容为:
UseDNS no
GSSAPIAUTCATTON no
permitRootLogin no
 #方法一
 cat >> config << EOF
 UseDNS no
GSSAPIAUTCATTON no
permitRootLogin no
EOF
#如果要追加的内容包含特殊符号,则在EOF两边加是‘’
#方法二
sed '$a UseDNS no\GSSAPIAUTCATTON no\permitRootLogin no'  config

6)替换:s

替换格式:

语法:sed 's#xxx#xxx#g'
  s:#想要的搜索内容#想替换的内容#g   
  s:搜索                     g:全局

反向引用:

口诀:先保护,在使用

例:把hello,world前后反过来
[root@hadoop102 ~]# echo hello,world 
hello,world
[root@hadoop102 ~]# echo hello,world | sed -r 's#(^.*),(.*$)#\2 \1#g'
world hello

注:尽量使用#

awk

1)awk基本概念

  awk 是一个按需求格式化文本再进行输出的工具。
  和 sed 命令类似,awk 命令也是逐行扫描文件(从第 1 行到最后一行),寻找含有目标文本的行,如果匹配成功,则会在该行上执行用户想要的操作;反之,则不对行做任何处理。
  awk -f 脚本文件 数据文件  执行awk脚本文件
  awk 的应用场景:
看下 awk 能干些什么事情:
1. 能够将给定的文本内容,按照我们期望的格式输出显示,打印成报表。
2. 分析处理系统日志,快速地分析挖掘我们关心的数据,并生成统计信息;
3. 方便地用来统计数据,比如网站的访问量,访问的 IP 量等;
4. 通过各种工具的组合,快速地汇总分析系统的运行信息,让你对系统的运行了如指掌;
5. 强大的脚本语言表达能力,支持循环、条件、数组等语法,助你分析更加复杂的数据;
awk 不是万能的,它比较擅长处理格式化的文本,比如 日志、 csv 格式数据等;

awk 的工作流程图如图

image-20230706172922934

工作原理:

逐行读取文本,默认以空格或tab键为分隔符进行分隔,将分隔所得的各个字段保存到内建变量中,并按模式或者条件执行编辑命令。

在使用awk命令的过程中,可以使用逻辑操作符“&&”表示“与”、“||”表示“或”、“!”表示“非”;还可以进行简单的数学运算,如+、-、*、/、%、^分别表示加、减、乘、除、取余和乘方。

2)语法

举例:
# awk -F: 'BEGIN{print"-----header-----"} {print $1,$7} END{print"-----footer-----"}' /etc/passwd

3)awk结构

1. BEGIN 区域
Begin 区域的语法:
BEGIN { awk-commands }
BEGIN 区域的命令只最开始、在 awk 执行 body 区域命令之前执行一次。
BEGIN 区域很适合用来打印报文头部信息,以及用来初始化变量。
BEGIN 区域可以有一个或多个 awk 命令
关键字 BEGIN 必须要用大写
BEGIN 区域是可选的
2. body 区域
body 区域的语法:
/pattern/ {action}
body 区域的命令每次从输入文件读取一行就会执行一次
如果输入文件有 10 行,那 body 区域的命令就会执行 10 次(每行执行一次)
Body 区域没有用任何关键字表示,只有用正则模式和命令。
Body 区域是可选的
3. END 区域
END 区域的语法:
END { awk-commands }
END 区域在 awk 执行完所有操作后执行,并且只执行一次。
END 区域很适合打印报文结尾信息,以及做一些清理动作
END 区域可以有一个或多个 awk 命令
关键字 END 必须要用大写
END 区域是可选的
提示:如果命令很长,即可以放到单行执行,也可以用\折成多行执行。

行与列

名词 awk一些叫法 一些说明
记录(record) 每一行默认通过回车分割的
字段(field) 每一列默认通过空格分割的
awk中行与列结束的标记都是可以修改的
内置变量 功能
NF 当前处理的行的字段个数(就是:有多少列)
NR 当前处理的行的行号(就是:有多少行)例:NR==1[取出某一行]
FNR 读取文件的记录数(行号),从1开始,新的文件重新从1开始计数
$0 当前处理的行的整行内容(就是:表示一行的内容)
$n 当前处理行的第n个字段(就是:第n列)
FILENAME 被处理的文件名
FS 指定每行的字段分隔符,默认为空格或制表位(相当于选项 -F )
OFS 输出字段的分隔符,默认也是空格
RS 行分割符。awk从文件上读取资料时,将根据Rs的定义把资料切割成许多条记录,而awk一次仅读取一条记录,预设值是“\n“
ORS 输出分割符,默认也是换行符

1)取行

awk
NR==1 取出某一行
NR>=1&&(并且)NR<=5 取出1到5行范围
常用符号 > < = >= <= == !=(不等于)
/jiujiu/ //(双斜线搜索/过滤)
/xx/,/xx/ 例:[root@hadoop102 ~]# awk '/1/,/4/' like
1hello ,world
2like
4linux

2)取列

在awk中取列首先要认识-F

  • -F:指定分隔符,指定每一列结束标记(默认是空格/连续的空格/还有tab键)
  • $数字:表示取出某一列 注意:在awk中$内容一个意思,表示取出某一列
  • $0:表示整行的内容
  • 取列一般是{print xxx}
  • $NF:表示取最后一列

小结

  • 行与列的认知,[行:记录 列:字段/域]
  • awk取行与取列

awk模式匹配

awk -F"[ /]+" 'NR==2{print $2}'
命令 选项 ‘条件{动作}’
  • 比较符号:<(小于) >(大于) =(等于) >=(大于等于) <=(小于等于) !=(不等于)
  • 正则:
  • 范围: 表达式 ;
  • 特殊条件:BEGIN和END

1)比较表达式-参考上面取行部分

2)正则:

  • //(双划线) 支持扩展正则
  • awk可以精确到某一列,某一列中包含/不包含.......内容
  • ~ :包含
  • !~:不包含
正则 awk正则
^ 表示.....开头 某一列的开头 $2~/^like/ :第二列以like开头的
$ 表示.....结尾 某一列的结尾 $2~/like$/ :第二列以like结尾的
^$ 空行 某一列的空的 $2~/^$/ :第二列空行的
练习:
#找出第三列以2开头的行,并显示第一列,第三列,最后一列
文件:/etc/passwd
[root@hadoop102 ~]# awk -F: '$3~/^2/' /etc/passwd| awk -F : '{print $1,$3,$NF}'
#取找出第三列以1或者2开头的行,并显示第一列,第三列,最后一列
 awk -F: '$3~/^[12]/' /etc/passwd| awk -F : '{print $1,$3,$NF}'
 awk -F: '$3~/^1|^2/' /etc/passwd| awk -F : '{print $1,$3,$NF}'
 可以多种写法,主要看正则怎么写

3)表示范围

  • /从哪里开始/./哪里结束/ 常用
  • NR==1,NR==5 从第一行开始到第五行结束 类似于sed -n '1,5p'

4)特殊模式BEGIN{}和END{}

模式 含义 应用场景
BEGIN 里面的内容会在awk读取文件之前执行 1)进行简单的统计,计算,不涉及读取文件(常用
2)用来处理文件之前,添加个表头(了解)
3)用来定义awk变量(很少用,因为可以用-v)
END 里面的内容会在awk读取文件之后执行 1)awk进行统计,一般是过程;先进行计算,最后END里面输出结果(常用)
2)awk使用数组,用来输出数组结果(常用)
  • END{}统计计算

  • 统计方法:

    统计方法 简写形式 应用场景
    i++ i=i+1 计数型,统计次数
    sum=sum+?? sum+=?? 求和,累加
    注意:i sum 都是变量,可以随便写
    array[]=array[]+1 array[]++ 数组分类计算
统计/etc/service里面有多少个空行
[root@hadoop102 ~]# awk '/^$/{i++}END{print i}' /etc/services 
17
#求1到100的和
[root@hadoop102 ~]# seq 100|awk '{sum=sum+$1}END{print sum}'
5050
如果要显示过程则:
在条件后跟上print xxx
[root@hadoop102 ~]# seq 100|awk '{sum=sum+$1,print sum}END{print sum}'

5)awk数组

  • 统计日志:类似于统计个每个ip出现的字数,统计每种状态码出现的次数/统计系统中每个用户被攻击的次数等等...
  • 累加求和;统计每个ip消耗的流量
shell数组 awk数组
形式 array[0]=jiujiu array[1]=like array[0]=jiujiu array[1]=like
使用 echo $(array[0]) echo $(array[1]) print array[0] array[1]
批量输出数组内容 for i in $(array[*])
do
echo $i
done
for (i in array)
print i
print [i]
awk数组专用循环,变量获取到的是数组的下标,如果想要数组内容 用 a[i] 注释1
#awk数组一般定义和使用
[root@hadoop102 ~]# awk 'BEGIN{a[0]=jiujiu;a[1]=like; print a[0],a[1]}'

[root@hadoop102 ~]# #这里显示空白是因为在awk中字母会被识别为变量,如果只是想
[root@hadoop102 ~]# #使用字符串需要用双引号引起来
[root@hadoop102 ~]# #数字不受影响
[root@hadoop102 ~]# awk 'BEGIN{a[0]=123;a[1]=321; print a[0],a[1]}'
123 321
[root@hadoop102 ~]# awk 'BEGIN{a[0]="jiujiu";a[1]="like"; print a[0],a[1]}'
jiujiu like
#注释1:awk数组专用
[root@hadoop102 ~]# awk 'BEGIN{a[0]=123;a[1]=321; for (i in a) print i}'
0
1
[root@hadoop102 ~]# awk 'BEGIN{a[0]=123;a[1]=321; for (i in a) print a[i]}'
123
321

练习题:

#统计以下域名出现次数(用awk)
https://blog.driverzeng.com/index.html
https://blog.driverzeng.com/index.html
https://blog.driverzeng.com/index.html
https://blog.driverzeng.com/1.html
http://post.driverzeng.com/index.html
https://blog.driverzeng.com/1.html
https://blog.driverzeng.com/1.html
http://mp3.driverzeng.com/index.html
https://blog.driverzeng.com/1.html
https://blog.driverzeng.com/3.html
http://post.driverzeng.com/2.html
http://post.driverzeng.com/2.html
http://post.driverzeng.com/2.html
http://post.driverzeng.com/2.html
http://post.driverzeng.com/2.html
http://post.driverzeng.com/2.html

[root@hadoop102 ~]# cat 111 | awk -F '/' '{array[$3]++}END{for (i in array)print i,array[i]}' 111 
blog.driverzeng.com 8
post.driverzeng.com 7
mp3.driverzeng.com 1

#array[]++ 你要统计什么  []里面就是什么(某一列
#比如:统计access.log中ip出现的次数  array[$1]

注意:使用awk统计日志,尽量精确匹配

6)for循环/if判断

shell编程c语言for循环 awk for循环
for((i=1;i<=10;i++))
do
echo '$i'
down
for(i=1;1<=10;i++)
print i
awk for循环用来循环每个字段
例:
1+100的和
[root@hadoop102 ~]# awk 'BEGIN{for(i=1;i<=100;i++)sum+=i;print sum}'
5050

[root@hadoop102 ~]# awk 'BEGIN{
for(i=1;i<=100;i++)
    sum+=i;
print sum
}'
5050

if判断

shell if 判断 awk if 判断
if["who" -eq 20 ];then
echo ’成年人’
fi
if(条件)
print "成年人”
常用
if["who" -eq 20 ];then
echo ’成年人’
else
echo "未成年人“
fi
if(条件)
print "成年人”
else
print "未成年人“

例子:

统计磁盘空间使用率,如果大于1%,则提示磁盘空间不足,并显示磁盘分区,磁盘使用率,磁盘挂载点
[root@hadoop102 ~]# df -h
Filesystem               Size  Used Avail Use% Mounted on
devtmpfs                 2.1G     0  2.1G   0% /dev
tmpfs                    2.1G     0  2.1G   0% /dev/shm
tmpfs                    2.1G   12M  2.1G   1% /run
tmpfs                    2.1G     0  2.1G   0% /sys/fs/cgroup
/dev/mapper/centos-root   45G  1.5G   44G   4% /
/dev/sda1                3.0G  138M  2.9G   5% /boot
tmpfs                    423M     0  423M   0% /run/user/0
[root@hadoop102 ~]# df -h | awk -F '[ %]+' 'NR>1{if($5>=1)print "disk no enough",$1,$5,$NF}'
disk no enough tmpfs 1 /run
disk no enough /dev/mapper/centos-root 4 /
disk no enough /dev/sda1 5 /boot
#注意:
awk使用多个条件的时候,第一个条件可以放在‘条件{动作}’ 第二个条件一般使用if判断

试题:

统计这段语句中,单词字符数小于6的单词 ,显示出来

Life is too short to spend time with people who suck the happiness out of you

[root@hadoop102 ~]# echo Life is too short to spend time with people who suck the happiness out of you
awk '{for(i=1;i<=NF;i++) if(length($i)<6) print $i}'
Life
is
too
short
to
spend
time
with
who
suck
the
out
of
you

awk函数

length:统计
[root@hadoop102 ~]# echo jiujiu | awk '{print length()}'
6
[root@hadoop102 ~]# echo jiujiu like | awk '{print length($1)}'
6
[root@hadoop102 ~]# echo jiujiu like | awk '{print length($2)}'
4
如果不属于$1/$2则默认$0整行输出

正则支持表

字符 说明 Basic RegEx Extended RegEx python RegEx Perl regEx
转义 \ \ \ \
^ 匹配行首,例如'^dog'匹配以字符串dog开头的行(注意:awk 指令中,'^'则是匹配字符串的开始) ^ ^ ^ ^
$ 匹配行尾,例如:'^、dog匹配以字符串为结尾的行(注意:指令中,'则是匹配字符串的结尾) $ $ $ $
^$ 匹配空行 ^$ ^$ ^$ ^$
^string$ 匹配行,例如:'^dog$'匹配只含一个字符串 dog 的行 ^string$ ^string$ ^string$ ^string$
< 匹配单词,例如:'<frog' (等价于'\bfrog'),匹配以 frog 开头的单词 < < 不支持 不支持(但可以使用\b来匹配单词,例如:'\bfrog')
> 匹配单词,例如:'frog>'(等价于'frog\b '),匹配以 frog 结尾的单词 > > 不支持 不支持(但可以使用\b来匹配单词,例如:'frog\b')
匹配一个单词或者一个特定字符,例如:''(等价于'\bfrog\b')、'' 不支持 不支持(但可以使用\b来匹配单词,例如:'\bfrog\b'
() 匹配表达式,例如:不支持'(frog)' 不支持(但可以使用,如:dogdog () () ()
匹配表达式,例如:不支持'(frog)' 不支持(同()) 不支持(同()) 不支持(同())
匹配前面的子表达式 0 次或 1 次(等价于{0,1}),例如:where(is)?能匹配"where" 以及"whereis" 不支持(同\?)
\? 匹配前面的子表达式 0 次或 1 次(等价于'{0,1}'),例如:'whereisis\? '能匹配 "where"以及"whereis" \? 不支持(同?) 不支持(同?) 不支持(同?)
? 当该字符紧跟在任何一个其他限制符(*, +, ?, {n},{n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 "oooo",'o+?' 将匹配单个"o",而 'o+' 将匹配所有 'o' 不支持 不支持 不支持 不支持
. 匹配除换行符('\n')之外的任意单个字符(注意:awk 指令中的句点能匹配换行符) . .(如果要匹配包括“\n”在内的任何一个字符,请使用:'(^$)|(.) . .(如果要匹配包括“\n”在内的任何一个字符,请使用:' [.\n] '
* 匹配前面的子表达式 0 次或多次(等价于{0, }),例如:zo* 能匹配 "z"以及 "zoo" * * * *
+ 匹配前面的子表达式 1 次或多次(等价于'{1, }'),例如:'whereisis+ '能匹配 "whereis"以及"whereisis" + 不支持(同+) 不支持(同+) 不支持(同+)
+ 匹配前面的子表达式 1 次或多次(等价于{1, }),例如:zo+能匹配 "zo"以及 "zoo",但不能匹配 "z" 不支持(同+) + + +
{n} n 必须是一个 0 或者正整数,匹配子表达式 n 次,例如:zo{2}能匹配 不支持(同{n}) {n} {n} {n}
{n,} "zooz",但不能匹配 "Bob"n 必须是一个 0 或者正整数,匹配子表达式大于等于 n次,例如:go{2,} 不支持(同{n,}) {n,} {n,} {n,}
{n,m} 能匹配 "good",但不能匹配 godm 和 n 均为非负整数,其中 n <= m,最少匹配 n 次且最多匹配 m 次 ,例如:o{1,3}将配"fooooood" 中的前三个 o(请注意在逗号和两个数之间不能有空格) 不支持(同{n,m}) {n,m} {n,m} {n,m}
x|y 匹配 x 或 y,例如: 不支持'z|(food)' 能匹配 "z" 或"food";'(z|f)ood' 则匹配"zood" 或 "food" 不支持(同x|y) x|y x|y x|y
[0-9] 匹配从 0 到 9 中的任意一个数字字符(注意:要写成递增) [0-9] [0-9] [0-9] [0-9]
[xyz] 字符集合,匹配所包含的任意一个字符,例如:'[abc]'可以匹配"lay" 中的 'a'(注意:如果元字符,例如:. *等,它们被放在[ ]中,那么它们将变成一个普通字符) [xyz] [xyz] [xyz] [xyz]
[^xyz] 负值字符集合,匹配未包含的任意一个字符(注意:不包括换行符),例如:'[^abc]' 可以匹配 "Lay" 中的'L'(注意:[^xyz]在awk 指令中则是匹配未包含的任意一个字符+换行符) [^xyz] [^xyz] [^xyz] [^xyz]
[A-Za-z] 匹配大写字母或者小写字母中的任意一个字符(注意:要写成递增) [A-Za-z] [A-Za-z] [A-Za-z] [A-Za-z]
[^A-Za-z] 匹配除了大写与小写字母之外的任意一个字符(注意:写成递增) [^A-Za-z] [^A-Za-z] [^A-Za-z] [^A-Za-z]
\d 匹配从 0 到 9 中的任意一个数字字符(等价于 [0-9]) 不支持 不支持 \d \d
\D 匹配非数字字符(等价于 [^0-9]) 不支持 不支持 \D \D
\S 匹配任何非空白字符(等价于[^\f\n\r\t\v]) 不支持 不支持 \S \S
\s 匹配任何空白字符,包括空格、制表符、换页符等等(等价于[ \f\n\r\t\v]) 不支持 不支持 \s \s
\W 匹配任何非单词字符 (等价于[^A-Za-z0-9_]) \W \W \W \W
\w 匹配包括下划线的任何单词字符(等价于[A-Za-z0-9_]) \w \w \w \w
\B 匹配非单词边界,例如:'er\B' 能匹配 "verb" 中的'er',但不能匹配"never" 中的'er' \B \B \B \B
\b 匹配一个单词边界,也就是指单词和空格间的位置,例如: 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的'er' \b \b \b \b
\t 匹配一个横向制表符(等价于 \x09和 \cI) 不支持 不支持 \t \t
\v 匹配一个垂直制表符(等价于 \x0b和 \cK) 不支持 不支持 \v \v
\n 匹配一个换行符(等价于 \x0a 和\cJ) 不支持 不支持 \n \n
\f 匹配一个换页符(等价于\x0c 和\cL) 不支持 不支持 \f \f
\r 匹配一个回车符(等价于 \x0d 和\cM) 不支持 不支持 \r \r
\ 匹配转义字符本身"" \ \ \ \
\cx 匹配由 x 指明的控制字符,例如:\cM匹配一个Control-M 或回车符,x 的值必须为A-Z 或 a-z 之一,否则,将 c 视为一个原义的 'c' 字符 不支持 不支持 \cx
\xn 匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长,例如:'\x41' 匹配 "A"。'\x041' 则等价于'\x04' & "1"。正则表达式中可以使用 ASCII 编码 不支持 不支持 \xn
\num 匹配 num,其中 num是一个正整数。表示对所获取的匹配的引用 不支持 \num \num
[:alnum:] 匹配任何一个字母或数字([A-Za-z0-9]),例如:'[[:alnum:]] ' [:alnum:] [:alnum:] [:alnum:] [:alnum:]
[:alpha:] 匹配任何一个字母([A-Za-z]), 例如:' [[:alpha:]] ' [:alpha:] [:alpha:] [:alpha:] [:alpha:]
[:digit:] 匹配任何一个数字([0-9]),例如:'[[:digit:]] ' [:digit:] [:digit:] [:digit:] [:digit:]
[:lower:] 匹配任何一个小写字母([a-z]), 例如:' [[:lower:]] ' [:lower:] [:lower:] [:lower:] [:lower:]
[:upper:] 匹配任何一个大写字母([A-Z]) [:upper:] [:upper:] [:upper:] [:upper:]
[:space:] 任何一个空白字符: 支持制表符、空格,例如:' [[:space:]] ' [:space:] [:space:] [:space:] [:space:]
[:blank:] 空格和制表符(横向和纵向),例如:'[[:blank:]]'ó'[\s\t\v]' [:blank:] [:blank:] [:blank:] [:blank:]
[:graph:] 任何一个可以看得见的且可以打印的字符(注意:不包括空格和换行符等),例如:'[[:graph:]] ' [:graph:] [:graph:] [:graph:] [:graph:]
[:print:] 任何一个可以打印的字符(注意:不包括:[:cntrl:]、字符串结束符'\0'、EOF 文件结束符(-1), 但包括空格符号),例如:'[[:print:]] ' [:print:] [:print:] [:print:] [:print:]
[:cntrl:] 任何一个控制字符(ASCII 字符集中的前 32 个字符,即:用十进制表示为从 0 到31,例如:换行符、制表符等等),例如:' [[:cntrl:]]' [:cntrl:] [:cntrl:] [:cntrl:] [:cntrl:]
[:punct:] 任何一个标点符号(不包括:[:alnum:]、[:cntrl:]、[:space:]这些字符集) [:punct:] [:punct:] [:punct:] [:punct:]
[:xdigit:] 任何一个十六进制数(即:0-9,a-f,A-F) [:xdigit:] [:xdigit:] [:xdigit:] [:xdigit:]
0