linux文本处理三剑客之awk

 4.1特点与应用场景

awk

一门语言,类似于C语言
过滤,统计,计算
过滤,统计日志

4.2 awk内置变量

                                                                                                                                                                                                                                                                            
            

内置变量

            
            

示例

            
            

NR

            
            

Number or Record 记录号,行号

            
            

NF

            
            

Number of Field 每行有多个字段(列) $NF表示最后一列

            
            

awk '{print $NF}'  文件名

            
            

FS

            
            

-F:    ===-v FS=:  Field Separator 字段分隔符,每个字段结束标记

            
            

OFS

            
            

Output Field Separator 输出字段分隔符,(awk显示每一列的时候,每一列之间通过什么分割,默认是空格)

            
            

awk -F: -v OFS=: '{print $NF,$2,$3,$4,$5,$6,$1}' 文件名

            

4.3行与列

                                                                                                                                                                                                                        
            

名词

            
            

awk中叫法

            
            

一些说明

            
            

            
            

记录record

            
            

每一行默认通过回车分割

            
            

            
            

字段域field

            
            

每一列默认通过空格分割

            
            

awk中行和列结束标记都是可以修改的

            

   

1)取行

                                                                                                                                                                                                                                                                                                                                
            

awk

            
            

示例

            
            

NR==1

            
            

取出某一行

            
            

awk 'NR==1' access.log.20220304000301

            
            

NR>1&&NR<=5

            
            

取出1到5行范围

            
            

/oldboy/

            
            

/101/,/105/

            
            

符号

            
            

> < >= <= == !=

            

2)取列

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

取网卡地址

只取个ip地址

3)小结

行与列名称
awk取行与列,指哪打哪
取出网卡ip地址

4.4 swk 模式匹配

谁可以作为awk的条件

                                                                                                                                                                                                                                                                            
            

awk

            
            

-F"{/}+"

            
            

'NR==3{print $3}'

            
            

命令

            
            

选项

            
            

'条件{动作}'

            
            

'模式{干啥}'

            
            

'模式{动作}'

            
            

'pattern{action}'

            

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

2)正则:

支持扩展正则
awk可以精确到某一列,某一行中包含/不包含.....内容。
~包含
!~不包含
                                                                                                                                                                                                                        
            

正则

            
            

awk正则

            
            

^表示以....开头的行

            
            

某一列的开头  $3~/^oldoy/

            
            

$表示以.....结尾的行

            
            

某一列的结尾$4~/lidao$/

            
            

^$表示空行

            
            

某一列是空的    很少用

            

   

#找出  第3列以2开头的行,并显示第1,3和最后一列

找出  第3列以1或2开头的行,并显示第1列,第3列和最后一列

还有这几种写法

3)表示范围

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


#显示指定时间(11:02:00到11:02:30)范围内容的ip地址和用户访问uri column -t(自动对齐)
awk '/11:02:00/,/11:02:30/{print $1}' access.log.20220304000301
awk '/11:02:00/,/11:02:30/{print $1,$7,$9,$10}' access.log.20220304000301 |column -t

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

                                                                                                                                                                    
            

模式

            
            

含义

            
            

应用场景

            
            

BEGIN{}

            
            

里面的内容会在awk读取文件之前执行

            
            

1)进行简单统计,计算,不涉及读取文件(常见)

            

2)用来处理文件之前,添加个表头(了解)

            

3)用来定义awk变量(很少用,因为可以用-***bsp;           

            

END{}

            
            

里面的内容会在awk读取文件之后执行

            
            

1)awk进行统计,一般过程;先进行计算,最后END里面输出结果(常见)

            

2)awk使用数组,用来输出数组结果。(常见)

            
        
  1.     

    END{}统计计算:

        
  2.     
  3.     

    统计方法

        
                                                                                                                                                                                                                        
            

统计方法

            
            

简写形式

            
            

应用场景

            
i=i+1             

i++

            
            

计数,统计次数

            
            

sum=sum+???

            
            

sum+=???

            
            

求和,累加

            
            

注意:i,sum都是变量

            
#统计/etc/services  里面有多少个空行
awk '/^$/' /etc/services

统计有多少空行

awk '/^$/{i++}END{print i}' /etc/services

#seq 100 求和1+2+3.。。+100 awk实现
seq 100 |awk '{sum=sum+$1}END{print sum}'

求和显示过程

seq 100 |awk '{sum=sum+$1;print sum}END{print sum}'

4.5 awk数组

        
  1.     

    统计日志:类似于

        
  2.     
  3.     

    统计次数:统计每个ip出现次数,统计每种状态码出现次数,统计系统中每个用户被攻击的次数,统计攻击者ip出现次数

        
  4.     
  5.     

    累加求和:统计每个ip消耗的流量。

        
                                                                                                                                                                                                                                                                        
            

shell数组

            
            

awk数组

            
            

形式

            
            

array[0]=oldboy array[1]=liao

            
            

array[0]=oldboy array[1]=liao

            
            

使用

            
            

echo ${array[0]} ${array[1]}

            
            

print array[0] array[1]

            
            

批量输出数组内容

            
            

for i in ${array[*]}

            

do

            

    echo $i

            

done

            
            

for(i in array)

            

      print array[i]

            
            

awk数组专用循环,变量获取到的是数组的下标

            

   

#awk中字母  会被识别为变量,如果只是想使用字符串需要使用双引号引起来  
awk 'BEGIN{a[0]=oldboy;a[1]=liao; print a[0],a[1]}'

所以无结果

数字和加双引号可以正常显示

awk数组专用循环打印

[root@heimajinpai ~]# awk 'BEGIN{a[0]=12306;a[1]="liao"; for(i in a) print i }'
0
1
[root@heimajinpai ~]# awk 'BEGIN{a[0]=12306;a[1]="liao"; for(i in a) print a[i] }'
12306
liao
[root@heimajinpai ~]# awk 'BEGIN{a[0]=12306;a[1]="liao"; for(i in a) print i,a[i] }'
0 12306
1 liao

案例:

http://www.etantian.org/index.html
http://www.etantian.org/1.html
http://post.etantian.org/2.html
http://mp3.etantian.org/3.html
http://www.etantian.org/4.html
http://post.etantian.org/5.html
[root@heimajinpai test]# awk -F"[/]+" '{print $2}' url.txt
www.etantian.org
www.etantian.org
post.etantian.org
mp3.etantian.org
www.etantian.org
post.etantian.org
[root@heimajinpai test]# awk -F"[/.]+" '{print $2}' url.txt
www
www
post
mp3
www
post
[root@heimajinpai test]# awk -F"[/.]+" '{array[$2]++}END{for(i in array)print i,array[i]}' url.txt
www 3(出现的次数)
mp3 1(出现的次数)
post 2(出现的次数)
#array[]++    你要统计什么 [] 里面就是什么(某一列)
awk -F"[/.]+" '{array[$2]++}END{for(i in array)print i,array[i]}' url.txt

#统计access.log中    每种状态码出现的次数(方式一)
awk  '{array[$10]++}END{for(i in array)print i,array[i]}' access.log.20220304000301 |sort -rnk2

#统计access.log中    每种状态码出现的次数(方式一)
awk '$10~/[0-9][0-9][0-9]/{array[$10]++}END{for(i in array)print i,array[i]}' access.log.20220304000301 |sort -rnk2

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


4.6 for循环

for n in 1 2 3
do
    echo $n
done
                                                            
            

for(i=1;i<10;i++)

            

do

            

     echo $i

            

done

            
            

for(i=1;i<10;i++)

            

print i

            
            

awk for循环用来循环每个字段

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

4.7if 判断

统计磁盘空间使用率,如果大于70%,则提示磁盘空间不足,并显示磁盘分区,磁盘使用率,磁盘挂载点

df -h |awk -F"[ %]+" 'NR>1{if($5>=70)print "disk not enough"}'

df -h |awk -F"[ %]+" 'NR>1{if($5>=1)print "disk not enough",$1,$5,$NF}'

注意:awk使用多个条件的时候  第1个条件可以放在 ‘条件{动作}’ 第2个条件  一般使用if

面试题:统计这段语句中,单词中字符小于6的单词,显示出来。

4.9总结

微信公众号:黑马金牌编程


Linux系列 文章被收录于专栏

本专栏收录Linux系列内容,包括但不限于中间件、shell

全部评论

相关推荐

点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务