提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
一、特点域应用场景
- awk 一门语言,类似C语言 用于过滤,统计,计算,日志
二、执行过程
eg:文本 1.txt
echo 1.txt
101,oldboy,CEO
102,zhangyao,CTO
103,lidao,CFO
104,yy,cfo
110,yuyan,COCO
-->awk -F, 'BEGIN{print "name"}{print $2}END{print "end of file"}' 1.txt
name
oldboy
zhangyao
lidao
yy
yuyan
end of file
-->awk -F, 'BEGIN{print "name"}NR==3{print $2}END{print "end of file"}' 1.txt
name
zhangyao
end of file
三、AWK中的行与列
名字 | awk叫法与说明 |
---|---|
行 | 记录 record,每一行默认通过回车分割的 |
列 | 字段,域 field,每一列默认通过空格分割的 |
注:awk中行和列结束的标记都是可以修改的。
1)awk的内置变量
变量名 | 描述 |
---|---|
NR | Number of Record 记录行号 |
NF | Number of field 每行有多少字段(列)$NF表示最后一列 |
FS | -F :等于 -v FS=: field separator 字段分隔符 |
OFS | Output field separator 字段分隔符 |
2)awk取行
常用的awk取行条件 | 说明 |
---|---|
NR==n | 取出第n行 |
NR>=1 && NR <=5 | 取出1到5行 |
/oldboy/ | 过滤,包含内容的行 |
/101/,/105/ | 包含101的行到包含105的行 |
$0 | 整行的内容 |
符号 | <, <=,>,>=,==,!= |
--> awk 'NR==1' 1.txt
101,oldboy,CEO
--> awk 'NR>=1 && NR <=5' 1.txt
101,oldboy,CEO
102,zhangyao,CTO
103,lidao,CFO
104,yy,cfo
110,yuyan,COCO
--> awk '/oldboy/' 1.txt
101,oldboy,CEO
--> awk '/101/,/105/' 1.txt
101,oldboy,CEO
102,zhangyao,CTO
103,lidao,CFO
104,yy,cfo
110,yuyan,COCO
/哪里开始/,/哪里结束/ 常用
NR==1,NR==5 从第一行到di5行
--> awk '/101/,/103/' 1.txt
101,oldboy,CEO
102,zhangyao,CTO
103,lidao,CFO
--> awk 'NR==1,NR==3' 1.txt
101,oldboy,CEO
102,zhangyao,CTO
103,lidao,CFO
2)awk取列
常用的awk取列条件 | 说明 |
---|---|
-F | 指定分隔符,指定每一列的结束标记,默认是空格、连续的空格,tab键 |
$n | 取出第n列 |
{print $n} | 打印第n列 |
--> ls -al
-rw-rw-r-- 1 yuha nba 72 Nov 17 00:58 1.txt
--> ls -l | awk '{print $3}'
yuha
--> ls -l | awk 'NR==2{print $0}'
-rw-rw-r-- 1 yuha nba 72 Nov 17 00:58 1.txt
--> ls -l | awk '{print $5,$9}'
72 1.txt
--> ls -l | awk '{print $5,$9}' | column -t
72 1.txt
--> ls -l | awk '{print $5,$NF}' | column -t
72 1.txt
//column -t 加tab键对齐
文本 1.txt
echo 1.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
deamon:x:2:3:deamon:/sbin:/sbin/nologin
admin:x:3:4:admin:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
--> awk -F: '{print $1,$NF}' 1.txt | column -t
root /bin/bash
bin /sbin/nologin
deamon /sbin/nologin
admin /sbin/nologin
lp /sbin/nologin
//调换第一列和最后一列
--> awk -F: '{print $NF,$2,$3.$4,$5,$6,$1}' 1.txt | column -t
/bin/bash x 00 root /root root
/sbin/nologin x 11 bin /bin bin
/sbin/nologin x 23 deamon /sbin deamon
/sbin/nologin x 34 admin /var/adm admin
/sbin/nologin x 47 lp /var/spool/lpd lp
//但是中间的“:”没有了,方法一: ,$2,":",$3每个中间加":"
//方法二:
--> awk -F: -vOFS=: '{print $NF,$2,$3.$4,$5,$6,$1}' 1.txt | column -t
/bin/bash:x:00:root:/root:root
/sbin/nologin:x:11:bin:/bin:bin
/sbin/nologin:x:23:deamon:/sbin:deamon
/sbin/nologin:x:34:admin:/var/adm:admin
/sbin/nologin:x:47:lp:/var/spool/lpd:lp
取ip地址:
--> ip a s lo | awk -F "[ /]+" 'NR==3{print $3}'
127.0.0.1
//-F "[ /]+" 可以使用正则表达式,[ /]空格或者斜线 +表示多个,合起来就多个空格或者斜线为分割符
四、awk模式匹配
awk | -F “[ /]+” | ‘NR==3{print $3}’ |
---|---|---|
命令 | 选项 | ‘条件{动作}’ |
‘找谁{干啥}’ | ||
‘模式{动作}’ | ||
‘pattren{action}’ |
注:谁可以作为AWK的条件:
1)比较符号
2)正则
3)范围,表达式//
4)特殊条件BEGIN和END
5)比较符号-参考上面取行部分
6)正则
//支持扩展正则 //中写正则
awk可以精确到某一列,某一列包含/不包含…内容,符号:~ (包含) ~!(不包含)
正则 | awk |
---|---|
^以什么开头的行 | 某一列开头$3~/^oldboy/ |
$以什么结尾的行 | 某一列结尾$4~/^lidao/ |
^$表示空行 | 某一列是空的 |
第三列以1开头的行
--> awk -F: '$3~/^1/' 1.txt
bin:x:1:1:bin:/bin:/sbin/nologin
lp:x:1:1:lp:/var/spool/lpd:/sbin/nologin
deamon:x:1:3:deamon:/sbin:/sbin/nologin
找出第三列以1开头的行,并显示第1,3,最后一列
--> awk -F: '$3~/^1/{print $1, $3, $NF}' 1.txt | column -t
bin 1 /sbin/nologin
lp 1 /sbin/nologin
deamon 1 /sbin/nologin
找出第三列以1或者2开头的行,并显示第1,3,最后一列
--> awk -F: '$3~/^[12]/{print $1, $3, $NF}' 1.txt | column -t
/哪里开始/,/哪里结束/ 常用
NR==1,NR==5 从第一行到di5行
--> awk '/101/,/103/' 1.txt
101,oldboy,CEO
102,zhangyao,CTO
103,lidao,CFO
--> awk 'NR==1,NR==3' 1.txt
101,oldboy,CEO
102,zhangyao,CTO
103,lidao,CFO
4)特殊符号
模式 | 含义 | 应用场景 |
---|---|---|
BEGIN{} | 里面的内容会在awk读取文件之前执行. | 1)进行简单统计,计算,不涉及读取文件; 2)用来处理文件之前添加表头; 3)用来定义awk变量,很少用,因为可以用-v |
END{} | 里面的内容会在awk读取文件之后执行 | 1)awk进行统计一般过程,先进行计算,最后END里面输出结果 2)awk使用数组,最后输出结果 |
END统计计算:
统计方法 | 简写形式 | 应用场景 |
---|---|---|
i=i+1 | i++ | 计数统计次数 |
Sum=sum+? | Sum+=? | 求和 |
array[]=array[]+1 | array[]++ | 数组分类计数 |
注意 i sum都是变量
统计1.txt中的空行
--> awk '/^$/{i++}END{print i}' 1.txt
3
--> seq 100 | awk '{sum+=$1}END{print sum}'
5050
--> seq 100 | awk '{sum+=$1;print sum}END{print sum}'
5050
五、awk数组
统计日志,类似于统计每个ip出现的次数,统计系统中每个用户被攻击的次数,统计攻击者ip出现的次数
累加求和,统计每个ip的流量。
shell | 数组 | awk数组 | |
---|---|---|---|
形式 | array[0]=oldboy, array[1]=lidao, | array[0]=oldboy, array[1]=lidao, | |
使用 | echo ${array[0]} ${array[0]} | print array[0] array[1] | |
批量输出数组内容 | for I in ${array[*]} do echo $i done | for (i in array) print i,array[i] | awk数组专用循环,i为数组下标 |
注意awk ‘BEGIN{a[0]=oldboy;a[1]=lidao;print a[0],a[1]}’ awk字母会被识别为变量,如果只是想使用字符串需要使用双引号
awk 'BEGIN{a[0]="oldboy";a[1]="lidao";print a[0],a[1]}
--> awk 'BEGIN{a[0]="oldboy";a[1]="lidao";print a[0],a[1]; for(i in a) print i,a[i]}'
oldboy lidao
0 oldboy
1 lidao
文本,处理以下内容,将域名取出并排列域名进行计数排序
http://www.etiantian.org/index.html
http://www.etiantian,org/1.html
http://post.etiantian.org/index.html
http://mp3.etiantian.org/index.html
http://www.etiantian,org/2.html
http://wwwetiantian,org/3.html
http://post.etiantian.org/1.html
--> awk -F "[/.]+" '{print $2}' 1.txt
www
www
post
mp3
www
www
post
--> awk -F "[/.]+" '{array[$2]++}END{for (i in array) print i,array[i]}' 1.txt
www 4
mp3 1
post 2
要统计什么[]里面就是什么(某一列)
--> awk -F "[/.]+" '{array[$2]++}END{for (i in array) print i,array[i]}' 1.txt
www 4
mp3 1
post 2
--> awk -F "[/.]+" '{array[$2]++}END{for (i in array) print i,array[i]}' 1.txt | sort -rnk2 //排序
www 4
post 2
mp3 1
六、循环for
shell编程C语言for循环 | awk for循环 | |
---|---|---|
for((i=1;i<=10;i++)) do print i echo $i done | for(i=1;i<=10;i++) print i | awk for循环用来循环每个字段 |
计算1加到100
awk 'BEGIN{for(i=1;i<=100;i++)sum+=i;print sum}'
5050
七、.if判断
shell if判断 | awk if |
---|---|
if[“oldhuang” -eq 18];then echo obj fi | if(条件) print “obj” |
df -h | awk -F"[ %]+" 'NR>1{if($5>95)print "disk not enough", $1, $5,$NF}'
注意:awk使用多个条件的时候 第一个条件可以放在 ‘条件{动作}’ 第2个条件 一般使用if
面试题:统计这段语句中,单词中字符数小于6的单词,显示出来。
echo I am oldboy teacher welcome to oldboy training class.
echo I am oldboy teacher welcome to oldboy training class. | awk -F "[ .]" '{for(i=1;i<=NF;i++) if(length($i)<6)print $i}'
I
am
to
class
总结
awk常用操作是提取转换文本文件内容,awk功能十分强大,几乎其它文本处理命令能做的,awk都能做。
$n:表示截取哪一列,通常和print一起使用
$0:表示整行内容
NF:表示该行有多少列
NR:表示该行的行号
F:表示读取文件的分隔符(默认空格)
OFS:表示输入的内容以什么为分割符(默认空格)
~:表示包含
!~:表示不包含
awk 数组
awk if判断