正则表达式
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次 |
5) ? 前一个字符出现0次或者1次
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 精确过滤
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 的工作流程图如图
工作原理:
逐行读取文本,默认以空格或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') |
匹配一个单词或者一个特定字符,例如:' |
不支持 | 不支持(但可以使用\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:] |