介绍

这些案例是我收集起来的,大多都是我自己遇到过的,有些比较经典,有些比较具有代表性。

这些awk案例我也录了相关视频的讲解awk 18个经典实战案例精讲,欢迎大家去瞅瞅。

插入几个新字段

在"a b c d"的b后面插入3个字段e f g

  1. echo a b c d|awk '{$3="e f g "$3}1'

格式化空白

移除每行的前缀、后缀空白,并将各部分左对齐。

  1. aaaa bbb ccc
  2. bbb aaa ccc
  3. ddd fff eee gg hh ii jj
  1. awk 'BEGIN{OFS="\t"}{$1=$1;print}' a.txt

执行结果:

  1. aaaa bbb ccc
  2. bbb aaa ccc
  3. ddd fff eee gg hh ii jj

筛选IPv4地址

从ifconfig命令的结果中筛选出除了lo网卡外的所有IPv4地址。

读取.ini配置文件中的某段

  1. [base]
  2. name=os_repo
  3. baseurl=https://xxx/centos/$releasever/os/$basearch
  4. gpgcheck=0
  5. enable=1
  6. [mysql]
  7. name=mysql_repo
  8. baseurl=https://xxx/mysql-repo/yum/mysql-5.7-community/el/$releasever/$basearch
  9. gpgcheck=0
  10. enable=1
  11. [epel]
  12. name=epel_repo
  13. baseurl=https://xxx/epel/$releasever/$basearch
  14. gpgcheck=0
  15. enable=1
  16. [percona]
  17. name=percona_repo
  18. baseurl = https://xxx/percona/release/$releasever/RPMS/$basearch
  19. enabled = 1
  20. gpgcheck = 0

根据某字段去重

去掉uid=xxx重复的行。

  1. 2019-01-13_12:00_index?uid=123
  2. 2019-01-13_13:00_index?uid=123
  3. 2019-01-13_14:00_index?uid=333
  4. 2019-01-13_15:00_index?uid=9710
  5. 2019-01-14_12:00_index?uid=123
  6. 2019-01-14_13:00_index?uid=123
  7. 2019-01-15_14:00_index?uid=333
  8. 2019-01-16_15:00_index?uid=9710
  1. awk -F"?" '!arr[$2]++{print}' a.txt

结果:

  1. 2019-01-13_12:00_index?uid=123
  2. 2019-01-13_14:00_index?uid=333
  3. 2019-01-13_15:00_index?uid=9710

次数统计

  1. portmapper
  2. portmapper
  3. portmapper
  4. portmapper
  5. portmapper
  6. portmapper
  7. status
  8. status
  9. mountd
  10. mountd
  11. mountd
  12. mountd
  13. mountd
  14. mountd
  15. nfs
  16. nfs
  17. nfs_acl
  18. nfs
  19. nfs
  20. nfs_acl
  21. nlockmgr
  22. nlockmgr
  23. nlockmgr
  24. nlockmgr
  25. nlockmgr
  1. awk '{arr[$1]++}END{OFS="\t";for(idx in arr){printf arr[idx],idx}}' a.txt

统计TCP连接状态数量

  1. $ netstat -tnap
  2. Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
  3. tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1139/sshd
  4. tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 2285/master
  5. tcp 0 96 192.168.2.17:22 192.168.2.1:2468 ESTABLISHED 87463/sshd: root@pt
  6. tcp 0 0 192.168.2017:22 192.168.201:5821 ESTABLISHED 89359/sshd: root@no
  7. tcp6 0 0 :::3306 :::* LISTEN 2289/mysqld
  8. tcp6 0 0 :::22 :::* LISTEN 1139/sshd
  9. tcp6 0 0 ::1:25 :::* LISTEN 2285/master

统计得到的结果:

  1. 5: LISTEN
  2. 2: ESTABLISHED

一行式:

  1. netstat -tna | awk '/^tcp/{arr[$6]++}END{for(state in arr){print arr[state] ": " state}}'
  2. netstat -tna | /usr/bin/grep 'tcp' | awk '{print $6}' | sort | uniq -c

统计日志中各IP访问非200状态码的次数

日志示例数据:

  1. 111.202.100.141 - - [2019-11-07T03:11:02+08:00] "GET /robots.txt HTTP/1.1" 301 169

统计非200状态码的IP,并取次数最多的前10个IP。

  1. # 法一
  2. awk '$8!=200{arr[$1]++}END{for(i in arr){print arr[i],i}}' access.log | sort -k1nr | head -n 10
  3. # 法二:
  4. awk '
  5. $8!=200{arr[$1]++}
  6. END{
  7. PROCINFO["sorted_in"]="@val_num_desc";
  8. for(i in arr){
  9. if(cnt++==10){exit}
  10. print arr[i],i
  11. }
  12. }' access.log

统计独立IP

​ url 访问IP 访问时间 访问人

  1. a.com.cn|202.109.134.23|2015-11-20 20:34:43|guest
  2. b.com.cn|202.109.134.23|2015-11-20 20:34:48|guest
  3. c.com.cn|202.109.134.24|2015-11-20 20:34:48|guest
  4. a.com.cn|202.109.134.23|2015-11-20 20:34:43|guest
  5. a.com.cn|202.109.134.24|2015-11-20 20:34:43|guest
  6. b.com.cn|202.109.134.25|2015-11-20 20:34:48|guest

需求:统计每个URL的独立访问IP有多少个(去重),并且要为每个URL保存一个对应的文件,得到的结果类似:

  1. a.com.cn 2
  2. b.com.cn 2
  3. c.com.cn 1

并且有三个对应的文件:

  1. a.com.cn.txt
  2. b.com.cn.txt
  3. c.com.cn.txt

代码:

处理字段缺失的数据

  1. ID name gender age email phone
  2. 1 Bob male 28 abc@qq.com 18023394012
  3. 2 Alice female 24 def@gmail.com 18084925203
  4. 3 Tony male 21 17048792503
  5. 4 Kevin male 21 bbb@189.com 17023929033
  6. 5 Alex male 18 ccc@xyz.com 18185904230
  7. 6 Andy female ddd@139.com 18923902352
  8. 7 Jerry female 25 exdsa@189.com 18785234906
  9. 8 Peter male 20 bax@qq.com 17729348758
  10. 9 Steven 23 bc@sohu.com 15947893212
  11. 10 Bruce female 27 bcbd@139.com 13942943905

当字段缺失时,直接使用FS划分字段来处理会非常棘手。gawk为了解决这种特殊需求,提供了FIELDWIDTHS变量。

FIELDWIDTH可以按照字符数量划分字段。

  1. awk '{print $4}' FIELDWIDTHS="2 2:6 2:6 2:3 2:13 2:11" a.txt

处理字段中包含了字段分隔符的数据

下面是CSV文件中的一行,该CSV文件以逗号分隔各个字段。

  1. Robbins,Arnold,"1234 A Pretty Street, NE",MyTown,MyState,12345-6789,USA

需求:取得第三个字段"1234 A Pretty Street, NE"。

当字段中包含了字段分隔符时,直接使用FS划分字段来处理会非常棘手。gawk为了解决这种特殊需求,提供了FPAT变量。

FPAT可以收集正则匹配的结果,并将它们保存在各个字段中。(就像grep匹配成功的部分会加颜色显示,而使用FPAT划分字段,则是将匹配成功的部分保存在字段$1 $2 $3...中)。

  1. echo 'Robbins,Arnold,"1234 A Pretty Street, NE",MyTown,MyState,12345-6789,USA' |\
  2. awk 'BEGIN{FPAT="[^,]+|\".*\""}{print $1,$3}'

取字段中指定字符数量

  1. 16 001agdcdafasd
  2. 16 002agdcxxxxxx
  3. 23 001adfadfahoh
  4. 23 001fsdadggggg

得到:

  1. 16 001
  2. 16 002
  3. 23 001
  4. 23 002
  1. awk '{print $1,substr($2,1,3)}'
  2. awk 'BEGIN{FIELDWIDTH="2 2:3"}{print $1,$2}' a.txt

行列转换

  1. name age
  2. alice 21
  3. ryan 30

转换得到:

  1. name alice ryan
  2. age 21 30
  1. awk '
  2. {
  3. for(i=1;i<=NF;i++){
  4. if(!(i in arr)){
  5. arr[i]=$i
  6. } else {
  7. arr[i]=arr[i]" "$i
  8. }
  9. }
  10. }
  11. END{
  12. for(i=1;i<=NF;i++){
  13. print arr[i]
  14. }
  15. }
  16. ' a.txt

行列转换2

文件内容:

  1. 74683 1001
  2. 74683 1002
  3. 74683 1011
  4. 74684 1000
  5. 74684 1001
  6. 74684 1002
  7. 74685 1001
  8. 74685 1011
  9. 74686 1000
  10. ....
  11. 100085 1000
  12. 100085 1001

文件就两列,希望处理成

  1. 74683 1001 1002 1011
  2. 74684 1000 1001 1002
  3. ...

就是只要第一列数字相同, 就把他们的第二列放一行上,中间空格分开

  1. {
  2. if($1 in arr){
  3. arr[$1] = arr[$1]" "$2
  4. } else {
  5. arr[$1] = $2
  6. }
  7. }
  8. END{
  9. for(i in arr){
  10. printf "%s %s\n",i,arr[i]
  11. }
  12. }

筛选给定时间范围内的日志

grep/sed/awk用正则去筛选日志时,如果要精确到小时、分钟、秒,则非常难以实现。

但是awk提供了mktime()函数,它可以将时间转换成epoch时间值。

  1. # 2019-11-10 03:42:40转换成epoch
  2. $ awk 'BEGIN{print mktime("2019 11 10 03 42 40")}'
  3. 1573328560

借此,可以取得日志中的时间字符串部分,再将它们的年、月、日、时、分、秒都取出来,然后放入mktime()构建成对应的epoch值。因为epoch值是数值,所以可以比较大小,从而决定时间的大小。

下面strptime1()实现的是将2019-11-10T03:42:40+08:00格式的字符串转换成epoch值,然后和which_time比较大小即可筛选出精确到秒的日志。

下面strptime2()实现的是将10/Nov/2019:23:53:44+08:00格式的字符串转换成epoch值,然后和which_time比较大小即可筛选出精确到秒的日志。

  1. BEGIN{
  2. # 要筛选什么时间的日志,将其时间构建成epoch值
  3. which_time = mktime("2019 11 10 03 42 40")
  4. }
  5. {
  6. # 取出日志中的日期时间字符串部分
  7. match($0,"^.*\\[(.*)\\].*",arr)
  8. # 将日期时间字符串转换为epoch值
  9. tmp_time = strptime2(arr[1])
  10. # 通过比较epoch值来比较时间大小
  11. if(tmp_time > which_time){
  12. print
  13. }
  14. }
  15. # 构建的时间字符串格式为:"10/Nov/2019:23:53:44+08:00"
  16. function strptime2(str ,dt_str,arr,Y,M,D,H,m,S) {
  17. dt_str = gensub("[/:+]"," ","g",str)
  18. # dt_sr = "10 Nov 2019 23 53 44 08 00"
  19. split(dt_str,arr," ")
  20. Y=arr[3]
  21. M=mon_map(arr[2])
  22. D=arr[1]
  23. H=arr[4]
  24. m=arr[5]
  25. S=arr[6]
  26. return mktime(sprintf("%s %s %s %s %s %s",Y,M,D,H,m,S))
  27. }
  28. function mon_map(str ,mons){
  29. mons["Jan"]=1
  30. mons["Feb"]=2
  31. mons["Mar"]=3
  32. mons["Apr"]=4
  33. mons["May"]=5
  34. mons["Jun"]=6
  35. mons["Jul"]=7
  36. mons["Aug"]=8
  37. mons["Sep"]=9
  38. mons["Oct"]=10
  39. mons["Nov"]=11
  40. mons["Dec"]=12
  41. return mons[str]
  42. }

去掉/**/中间的注释

示例数据:

  1. /*AAAAAAAAAA*/
  2. 1111
  3. 222
  4. /*aaaaaaaaa*/
  5. 32323
  6. 12341234
  7. 12134 /*bbbbbbbbbb*/ 132412
  8. 14534122
  9. /*
  10. cccccccccc
  11. */
  12. xxxxxx /*ddddddddddd
  13. cccccccccc
  14. eeeeeee
  15. */ yyyyyyyy
  16. 5642341

前后段落关系判断

从如下类型的文件中,找出false段的前一段为i-order的段,同时输出这两段。

  1. 2019-09-12 07:16:27 [-][
  2. 'data' => [
  3. 'http://192.168.100.20:2800/api/payment/i-order',
  4. ],
  5. ]
  6. 2019-09-12 07:16:27 [-][
  7. 'data' => [
  8. false,
  9. ],
  10. ]
  11. 2019-09-21 07:16:27 [-][
  12. 'data' => [
  13. 'http://192.168.100.20:2800/api/payment/i-order',
  14. ],
  15. ]
  16. 2019-09-21 07:16:27 [-][
  17. 'data' => [
  18. 'http://192.168.100.20:2800/api/payment/i-user',
  19. ],
  20. ]
  21. 2019-09-17 18:34:37 [-][
  22. 'data' => [
  23. false,
  24. ],
  25. ]
  1. BEGIN{
  2. RS="]\n"
  3. ORS=RS
  4. }
  5. {
  6. if(/false/ && prev ~ /i-order/){
  7. print tmp
  8. print
  9. }
  10. tmp=$0
  11. }

两个文件的处理

有两个文件file1和file2,这两个文件格式都是一样的。

需求:先把文件2的第五列删除,然后用文件2的第一列减去文件一的第一列,把所得结果对应的贴到原来第五列的位置,请问这个脚本该怎么编写?

  1. file1
  2. 50.481 64.634 40.573 1.00 0.00
  3. 51.877 65.004 40.226 1.00 0.00
  4. 52.258 64.681 39.113 1.00 0.00
  5. 52.418 65.846 40.925 1.00 0.00
  6. 49.515 65.641 40.554 1.00 0.00
  7. 49.802 66.666 40.358 1.00 0.00
  8. 48.176 65.344 40.766 1.00 0.00
  9. 47.428 66.127 40.732 1.00 0.00
  10. 51.087 62.165 40.940 1.00 0.00
  11. 52.289 62.334 40.897 1.00 0.00
  12. file2
  13. 48.420 62.001 41.252 1.00 0.00
  14. 45.555 61.598 41.361 1.00 0.00
  15. 45.815 61.402 40.325 1.00 0.00
  16. 44.873 60.641 42.111 1.00 0.00
  17. 44.617 59.688 41.648 1.00 0.00
  18. 44.500 60.911 43.433 1.00 0.00
  19. 43.691 59.887 44.228 1.00 0.00
  20. 43.980 58.629 43.859 1.00 0.00
  21. 42.372 60.069 44.032 1.00 0.00
  22. 43.914 59.977 45.551 1.00 0.00

18个awk的经典实战案例的更多相关文章

  1. 3.awk数组详解及企业实战案例

    awk数组详解及企业实战案例 3.打印数组: [root@nfs-server test]# awk 'BEGIN{array[1]="zhurui";array[2]=" ...

  2. (转)awk数组详解及企业实战案例

    awk数组详解及企业实战案例 原文:http://www.cnblogs.com/hackerer/p/5365967.html#_label03.打印数组:1. [root@nfs-server t ...

  3. 企业Shell面试题及企业运维实战案例(三)

    1.企业Shell面试题1:批量生成随机字符文件名案例 使用for循环在/oldboy目录下批量创建10个html文件,其中每个文件需要包含10个随机小写字母加固定字符串oldboy,名称示例如下: ...

  4. 使用MapReduce实现一些经典的案例

    在工作中,很多时候都是用hive或pig来自动化执行mr统计,但是我们不能忘记原始的mr.本文记录了一些通过mr来完成的经典的案例,有倒排索引.数据去重等,需要掌握. 一.使用mapreduce实现倒 ...

  5. 如何从40亿整数中找到不存在的一个 webservice Asp.Net Core 轻松学-10分钟使用EFCore连接MSSQL数据库 WPF实战案例-打印 RabbitMQ与.net core(五) topic类型 与 headers类型 的Exchange

    如何从40亿整数中找到不存在的一个 前言 给定一个最多包含40亿个随机排列的32位的顺序整数的顺序文件,找出一个不在文件中的32位整数.(在文件中至少确实一个这样的数-为什么?).在具有足够内存的情况 ...

  6. 基于SpringCloud的Microservices架构实战案例-架构拆解

    自第一篇< 基于SpringCloud的Microservices架构实战案例-序篇>发表出来后,差不多有半年时间了,一直也没有接着拆分完,有如读本书一样,也是需要契机的,还是要把未完成的 ...

  7. Flume实战案例运维篇

    Flume实战案例运维篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Flume概述 1>.什么是Flume Flume是一个分布式.可靠.高可用的海量日志聚合系统,支 ...

  8. shell脚本编程——生产实战案例

    生产实战案例     在日常的生产环境中,可能会遇到需要批量检查内网目前在线的主机IP地址有哪些,还可能需要检查这些在线的主机哪些端口是开放状态,因此依靠手工来检查是可以实现,但比较费时费力,所以需要 ...

  9. Jenkins 搭建企业实战案例 (发布与回滚)

    让我们的代码部署变得easy,不再难,Jenkins是一个可扩展的持续集成引擎,是一个开源软件项目,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能.Jenkins非常易于安装和配置,简单易用 ...

随机推荐

  1. Type of the default value for 'songs' prop must be a function

    eslint常会出现这样的错误提示,控制台打印:Type of the default value for 'songs' prop must be a function 解决办法有两种如下: 1:写 ...

  2. 当node版本升级到8.0以上带来的问题

    1.新增package-lock.json 2.相关babel更新 重新安装 $ npm install babel-preset-env --save-dev .babelrc文件修改 { + &q ...

  3. 一起来刷《剑指Offer》——不修改数组找出重复的数字(思路及Python实现)

    数组中重复的数字 在上一篇博客中<剑指Offer>-- 题目一:找出数组中重复的数字(Python多种方法实现)中,其实能发现这类题目的关键就是一边遍历数组一边查满足条件的元素. 然后我们 ...

  4. 快速学习ggplot2

    R语言里面一个比较重要的绘图包——ggplot2,是由Hadley Wickham于2005年创建,于2012年四月进行了重大更新,作者目前的工作是重写代码,简化语法,方便用户开发和使用.ggplot ...

  5. 自定义segue的方向

    花了挺久时间,终于通过google在stake overflow上找到了解决方式. 总结一下:重写一个custom的segue,在storyboard的右边设置segue为custom,并设置其对应的 ...

  6. Unity3D图像后处理特效——Depth of Field 3.4

    Depth of Field 3.4 is a common postprocessing effect that simulates the properties of a camera lens. ...

  7. Method Not Allowed (GET): /boxuegos/index/ 错误

    1,Method Not Allowed (GET) 请求方法不被允许, 错误原因:我调用的是index这个方法,但是我上面定义了一个空的子路由,所以页面加载不了,控制台出现Method Not Al ...

  8. 数据文件包解析工具类 RandomAccessFile

    public class ReadTextFile { public static void main(String[] args) { pic2txt(); parseFrmFile(); //ur ...

  9. 创建WebApi

    一.创建 Web 项目 使用vs创建项目,选择“ASP.NET Core Web 应用程序”模板,将项目命名为 TodoApi,然后单击“确定”. 在“新建 ASP.NET Core Web 应用程序 ...

  10. QHDYZ模拟赛20191027 提前透题

    你们想的美 我给你们透一下题目名称 别刷博客了快去做题