当前位置:   article > 正文

Linux - awk命令详解_linux awk

linux awk

目录

1.  awk命令

1.1  awk工作原理

1.2  awk语法

1.2.1  awk完整语法

示例:

1.2.1  awk工作流程

1.3  指定分隔符

1.3.1  -F 指定分隔符

1.3.2  指定输出分隔符

2.  free命令

2.1  free命令各项含义 

 2.1.1  什么时候会使用交换分区?

2.1.2  内核参数优化

2.2   常用选项

-m 以M为单位显示内存的使用情况

-h  以人类能读懂的格式显示

3.0  awk各种组合运用

3.1   awk进行计算

3.2   awk命令的引用shell变量 

3.3  awk内置函数

  length()函数

 substr()函数

3.4  awk的if和for循环

3.5 awk里的数组


1.  awk命令

awk: gawk - pattern scanning and processing language

1.1  awk工作原理

与sed一样,均是一行一行的读取,处理

sed作用于一整行的处理,而awk将一行分成数个字段来处理

字段:一段字符串 --》一段很多字符组成了一个字符串

#############################################

1.2  awk语法

1.2.1  awk完整语法

awk ‘BEGIN {commands} pattern {commands}END{commands}' file1

BEGIN:处理数据前执行的命令

END:处理数据后执行的命令

pattern:模式,每一行都执行的命令

BEGIN和END里的命令只是执行一次

pattern里的命令会匹配每一行去处理

示例:

  1. [root@localhost lianxi]# cat /etc/passwd|awk -F ":" 'BEGIN{print "###start###"} $3>500&&$3<2000 {print $1,$3}END{print "###end###"}'
  2. ###start###
  3. polkitd 999
  4. chrony 998
  5. xiaowang 1000
  6. chenhang 1001
  7. zhnagjian 1002
  8. zhangjian 1003
  9. wangshenghu 1004
  10. yalin 1005
  11. nginx 997
  12. lilanqing 1006
  13. califeng 1007
  14. cali123 1008
  15. shimengmeng 1010
  16. zhouyiwei 1011
  17. zhaojunjie 1013
  18. kimi 1014
  19. kimi2 996
  20. linhucong 1015
  21. kimi3 1016
  22. feng2 1018
  23. feng3 1019
  24. feng4 1020
  25. feng5 1021
  26. liudehua 1022
  27. liming 1023
  28. libai 1024
  29. xiaoxiao 1025
  30. xiyangyang 1026
  31. meiyangyang 1027
  32. lanyangyang 1028
  33. zhangwuji 1029
  34. liang 1030
  35. ###end###

awk -F ":" '{print $1,$2,$5}' /etc/passwd | head -5

  1. [root@localhost 7.4]# awk -F ":" '{print $1,$2,$5}' /etc/passwd | head -5
  2. root x root
  3. bin x bin
  4. daemon x daemon
  5. adm x adm
  6. lp x lp

-F ":"  :  awk选项,指定输入分割符为:,

'{print}'    : 固定语法

$1,$2,$5  :输出第一个,第二个,第五个字段

 ,  : 是输出分隔符,如果不加默认是没有分隔符的。

  1. [root@localhost 7.4]# awk -F ":" '{print $1$2$5}' /etc/passwd | head -5
  2. rootxroot
  3. binxbin
  4. daemonxdaemon
  5. admxadm
  6. lpxlp

############################################# 

1.2.1  awk工作流程

执行BEGIN{commands}语句块中的语句

从文件或stdin中读取第一行,看有无模式匹配,若无则执行{}中的语句

若有则检查该整行与pattern是否匹配,若匹配,则执行{}中的语句

若不匹配则不执行{}中的语句,接着读取下一行

重复这个过程,知道所有行被读取完毕

执行END{commands语句块中的语句}

BEGIN 和 END 部分只是执行一次

中间部分每一行都执行一次

 

#############################################

1.3  指定分隔符

1.3.1  -F 指定分隔符

awk默认分隔符为空白:

示例:

  1. [root@localhost 7.1]# cat grade.txt | awk '{print $2,$3,$4}'
  2. name chinese english
  3. cali 80 80
  4. tom 90 90
  5. jarry 70 100

分隔符不是空白时候可以使用-F选项来指定分隔符

  1. [root@localhost 7.1]# cat /etc/passwd | tail | awk -F ":" '{print $1,$3,$4}'
  2. sanle 9931 9932
  3. test 9932 9935
  4. wang 9933 9933
  5. zhao 9934 9934
  6. bobo 9935 9936
  7. hang 9936 9937
  8. mysql 27 27
  9. bailongma 9937 9938
  10. baigujing 9938 9939
  11. yutujing 9939 9940

############################################# 

1.3.2  指定输出分隔符

 使用OFS定义输出分隔符

OFS="@@" 指定输出分隔符为@@

  1. [root@localhost 7.6]# awk -F ":" 'OFS="@@"{print $1,$7}' passwd
  2. mysql@@/sbin/nologin
  3. bailongma@@/bin/bash
  4. baigujing@@/bin/bash
  5. yutujing@@/bin/bash
  6. rrrge@@/bin/bash

############################################# 

2.  free命令

free查看内存使用的命令

  1. [root@localhost 7.5]# free -m
  2. total used free shared buff/cache available
  3. Mem: 972 212 418 7 341 607
  4. Swap: 2047 0 2047

############################################# 

2.1  free命令各项含义 

 Mem :memory 内存

total : 是总的物理内存(内存条的大小)

used:使用了多2.11少内存

shared:共享内存消耗的空间   ---》进程和进程之间的通信方式

buff/cache    ---》buffer  cache  缓存

                        buffer :data from  memory  to  disk

                        cache: data from disk to memory

available : 可用的内存空间

                        一个新的进程他可以使用的内存空间 = free + buff和cache里的可用空间

swap(交换分区):从磁盘里划分出来的一块空间,用来当做内存使用,速度比较慢

                                    将不活跃的进程临时存放到交换分区,当物理内存不足时就会采用交换分区

############################################# 

 2.1.1  什么时候会使用交换分区?

内存消耗了70%时就会使用交换分区

依据:在/proc/sys/vm/swappiness 文件里面规定了这一指标

               如下:意思为当物理内存还有30%时采用交换分区

  1. [root@localhost 7.5]# cat /proc/sys/vm/swappiness
  2. 30

############################################# 

2.1.2  内核参数优化

内核参数优化,提升进程使用的效率,告诉系统尽可能多使用物理内存,物理内存速度快

  1. [root@localhost 7.5]# cat /proc/sys/vm/swappiness
  2. 30
  3. [root@localhost 7.5]# echo 0 >/proc/sys/vm/swappiness
  4. [root@localhost 7.5]# cat /proc/sys/vm/swappiness
  5. 0

 可以看到,当我们使用交换分区以后,可用内存增加了。

2.2   常用选项

-m 以M为单位显示内存的使用情况

-h  以人类能读懂的格式显示

############################################

3.0  awk各种组合运用

############################################# 

3.1   awk进行计算

例1:统计uid>1000并且使用shell是bash的用户的数量

  1. [root@localhost 7.6]# awk -F ":" '$3>1000&&$7 ~ /bash/{print $1,$3,$7; i++}END{print "uid大于1000并且shell是bash的人数有:"i"人"}' passwd
  2. chenhang 1001 /bin/bash
  3. zhnagjian 1002 /bin/bash
  4. zhangjian 1003 /bin/bash
  5. wangshenghu 1004 /bin/bash
  6. yalin 1005 /bin/bash
  7. lilanqing 1006 /bin/bash
  8. califeng 1007 /bin/bash
  9. cali123 1008 /bin/bash
  10. shimengmeng 1010 /bin/bash
  11. zhouyiwei 1011 /bin/bash
  12. zhaojunjie 1013 /bin/bash
  13. kimi 1014 /bin/bash
  14. linhucong 1015 /bin/bash
  15. kimi3 1016 /bin/bash
  16. feng2 1018 /bin/bash
  17. feng3 1019 /bin/bash
  18. feng4 1020 /bin/bash
  19. feng5 1021 /bin/bash
  20. liudehua 1022 /bin/bash
  21. liming 1023 /bin/bash
  22. xiaoxiao 1025 /bin/bash
  23. xiyangyang 1026 /bin/bash
  24. meiyangyang 1027 /bin/bash
  25. lanyangyang 1028 /bin/bash
  26. zhangwuji 1029 /bin/bash
  27. liang 1030 /bin/bash
  28. user01 9901 /bin/bash
  29. user02 9902 /bin/bash
  30. user03 9903 /bin/bash
  31. user04 9904 /bin/bash
  32. user05 9905 /bin/bash
  33. user06 9906 /bin/bash
  34. user07 9907 /bin/bash
  35. user08 9908 /bin/bash
  36. user09 9909 /bin/bash
  37. zhangheng 9921 /bin/bash
  38. zhaomin 9922 /bin/bash
  39. wuji 9923 /bin/bash
  40. liangluyao 9924 /bin/bash
  41. pingguo 9925 /bin/bash
  42. jingshi 9926 /bin/bash
  43. yueyang 9927 /bin/bash
  44. tangpj 9928 /bin/bash
  45. tangpz1 9929 /bin/bash
  46. sc1 9930 /bin/bash
  47. test 9932 /bin/bash
  48. wang 9933 /bin/bash
  49. zhao 9934 /bin/bash
  50. bobo 9935 /bin/bash
  51. hang 9936 /bin/bash
  52. bailongma 9937 /bin/bash
  53. baigujing 9938 /bin/bash
  54. yutujing 9939 /bin/bash
  55. rrrge 9940 /bin/bash
  56. uid大于1000并且shell是bash的人数有:54人

例2:显示第5行到第10行/etc/passed文件里的第3和第5字段的内容

  1. [root@localhost 7.6]# awk -F ":" 'NR>=5 && NR<=10{print NR,$3,$5}' passwd
  2. 5 4 lp
  3. 6 5 sync
  4. 7 6 shutdown
  5. 8 7 halt
  6. 9 8 mail
  7. 10 11 operator

############################################# 

3.2   awk命令的引用shell变量 

在awk里面使用已经定义好的变量要用双引号括起来,并且条件匹配注意转义。

字段求和

 

#############################################

3.3  awk内置函数

  length()函数

 统计没有设置密码的用户的数量以及用户名

  1. bobo
  2. hang
  3. mysql
  4. bailongma
  5. baigujing
  6. yutujing
  7. rrrge
  8. mengmeng1
  9. mengmeng2
  10. mengmeng3
  11. 没有设置密码的用户有87个

 substr()函数

类似于python的切片处理

例:输出使用shell是bash的用户的第7个字段的前4个字符,并输出用户名

 

例:输出密码字段长度小于2并且输出用户名字段的前2个字符,统计个数输出出来。

  1. [root@localhost 7.6]# awk -F : 'length($2)<=2 {print substr($1,1,2);num++}END{print num}' passwd
  2. ro
  3. bi
  4. da
  5. ad
  6. lp
  7. ha
  8. my
  9. ba
  10. ba
  11. yu
  12. rr
  13. me
  14. me
  15. me
  16. 87

############################################# 

3.4  awk的if和for循环

if语句后面执行多个命令的时候,使用{}括起来,最后的命令接;结尾,外面的else if 和 else前面就不用再接;了

 示例:使用awk命令来输出passwd文件里哪些是超级用户,系统用户,普通用户。

 

  1. [root@localhost 7.5]# awk -F ":" '{if($3 ==0 ) print $1"是超级用户";else if($3>1&&$3<=999) print $1"是系统用户"; else print $1"是普通用户"}' passwd
  2. root是超级用户
  3. bin是普通用户
  4. daemon是系统用户
  5. adm是系统用户
  6. lp是系统用户
  7. sync是系统用户
  8. shutdown是系统用户
  9. halt是系统用户
  10. mail是系统用户
  11. operator是系统用户
  12. games是系统用户
  13. ftp是系统用户
  14. nobody是系统用户
  15. systemd-network是系统用户
  16. dbus是系统用户
  17. polkitd是系统用户
  18. sshd是系统用户
  19. postfix是系统用户
  20. mysql是系统用户
  21. bailongma是普通用户
  22. baigujing是普通用户
  23. yutujing是普通用户

例:使用awk命令来输出passwd文件里哪些是超级用户,系统用户,普通用户。并输出各用户的个数。

  1. [root@localhost 7.6]# awk -F : '{if($3 == 0){print $1"是超级用户";num1++;}else if($3>1 && $3 <1000){print $1"是系统用户";num2++;}else{print $1 "是普通用户";num3++;}}END{print"超级用户有:"num1"系统用户有:"num2"普通用户有:"num3}' passwd
  2. root是超级用户
  3. bin是普通用户
  4. daemon是系统用户
  5. adm是系统用户
  6. lp是系统用户
  7. sync是系统用户
  8. shutdown是系统用户
  9. halt是系统用户
  10. mail是系统用户
  11. operator是系统用户
  12. games是系统用户
  13. tcpdump是系统用户
  14. sanle是普通用户
  15. test是普通用户
  16. wang是普通用户
  17. zhao是普通用户
  18. bobo是普通用户
  19. hang是普通用户
  20. mysql是系统用户
  21. bailongma是普通用户
  22. baigujing是普通用户
  23. yutujing是普通用户
  24. rrrge是普通用户
  25. mengmeng1是普通用户
  26. mengmeng2是普通用户
  27. mengmeng3是普通用户
  28. 超级用户有:1系统用户有:23普通用户有:63

############################################# 

3.5 awk里的数组

例:统计每个省份一共得到了多少票

  1. [root@localhost 7.6]# awk '{vote[$1]+=$3}END{for (i in vote) print i,vote[i]}' lianxi.txt | sort -n -k 2
  2. 河南 6
  3. 江西 9
  4. 山东 12
  5. 湖南 43

练习题:

对nginx的日志文件access.log进行分析,分析出单个ip地址累计下载获取的文件大小的总数(对每次访问数据的大小进行求和),显示下载总数最大的前100个ip地址和下载文件大小,按照下载文件大小的降序排列,显示格式如下:
175.8.134.239 3456
172.105.77.209 78956

61.147.15.67 112345678
 

答案示例:

[root@localhost 7.6]# awk '{access[$1]+=$10}END{for (i in access) print i,access[i]}' access.log |sort -k 2 -nr|head -100

以下是一段nginx服务的日志:

  1. [root@localhost 7.6]# cat nginx.log
  2. 2019-04-25T09:51:58+08:00|a.google.com|47.52.197.27|GET /v2/depth?symbol=aaa HTTP/1.1|200|24|-|apple
  3. 2019-04-25T09:52:58+08:00|b.google.com|47.75.159.123|GET /v2/depth?symbol=bbb HTTP/1.1|200|407|-|python-requests/2.20.0
  4. 2019-04-25T09:53:58+08:00|c.google.com|13.125.219.4|GET /v2/ticker?timestamp=1556157118&symbol=ccc HTTP/1.1|200|162|-|chrome
  5. 2019-04-25T09:54:58+08:00|d.shuzibi.co|-||HEAD /justfor.txt HTTP/1.0|200|0|-|-
  6. 2019-04-25T09:55:58+08:00|e.google.com|13.251.98.2|GET /v2/order_detail?apiKey=ddd HTTP/1.1|200|231|-|python-requests/2.18.4
  7. 2019-04-25T09:56:58+08:00|f.google.com|210.3.168.106|GET /v2/trade_detail?apiKey=eee HTTP/1.1|200|24|-|-
  8. 2019-04-25T09:57:58+08:00|g.google.com|47.75.115.217|GET /v2/depth?symbol=fff HTTP/1.1|200|397|-|python-requests/2.18.4
  9. 2019-04-25T09:58:58+08:00|h.google.com|47.75.58.56|GET /v2/depth?symbol=ggg HTTP/1.1|200|404|-|safari
  10. 2019-04-25T09:59:58+08:00|i.google.com|188.40.137.175|GET /v2/trade_detail?symbol=hhh HTTP/1.1|200|6644|-|-
  11. 2019-04-25T10:01:58+08:00|j.google.com|2600:3c01:0:0:f03c:91ff:fe60:49b8|GET /v2/myposition?apiKey=jjj HTTP/1.1|200|110|-|scan

1.计算每分钟的带宽

方法1:

  1. [root@localhost 7.6]# awk -F "|" '{print substr($1,1,16),$6}' nginx.log
  2. 2019-04-25T09:51 24
  3. 2019-04-25T09:52 407
  4. 2019-04-25T09:53 162
  5. 2019-04-25T09:54 200
  6. 2019-04-25T09:55 231
  7. 2019-04-25T09:56 24
  8. 2019-04-25T09:57 397
  9. 2019-04-25T09:58 404
  10. 2019-04-25T09:59 6644
  11. 2019-04-25T10:01 110

方法2:

  1. [root@localhost 7.6]# awk -F "|" '{bandwidth[(substr($1,1,16))]+=$6}END{for (i in bandwidth) print i,bandwidth[i]}' nginx.log
  2. 2019-04-25T10:01 110
  3. 2019-04-25T09:56 24
  4. 2019-04-25T09:57 397
  5. 2019-04-25T09:58 404
  6. 2019-04-25T09:59 6644
  7. 2019-04-25T09:51 24
  8. 2019-04-25T09:52 407
  9. 2019-04-25T09:53 162
  10. 2019-04-25T09:54 200
  11. 2019-04-25T09:55 231

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/192848?site
推荐阅读
相关标签
  

闽ICP备14008679号