首页 > 其他分享 >awk的经典实战案例

awk的经典实战案例

时间:2023-08-06 11:45:12浏览次数:28  
标签:实战 arr 00 案例 awk print 2019 com

前言

这些案例比较经典,有些比较具有代表性。

1.插入几个新字段

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

echo "a b c d" | awk '{$2=$2" e f g";print}'

2.格式化空白

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

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

aaaa    bbb     ccc
bbb     aaa     ccc
ddd     fff     eee     gg      hh      ii      jj

3.筛选IPv4地址

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

ifconfig | awk 'BEGIN{RS=""}NR==2{print $6}' 默认分隔符为空格
顺序无法保证,多个网卡无法取值
ifconfig | awk 'BEGIN{RS="";FS="\n"}!/lo/{$0=$2;FS=" ";$0=$0;print $2}'
这种方式先利用RS获取段落,然后通过FS分隔符为换行符获取行,这样第一行就是第一个字段,第二行为第二个字段,然后将$2赋值给$0,字段划分FS重新修改

 

##1.法-:

ifconfig | awk ' /inet / && ! ($2 ~/^127/ ){print $2 } '
#按段落读取
##2.法二:
ifconfig | awk 'BEGIN {RS=""} ! /lo/{print $6 }'
##3.法三:
ifconfig |\ 
awk ' BEGIN{RS="";FS=" \n" }!/lo/{$0=$2;FS=" " ; $0=$0 ; print $2 }

 

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

[base]
name=os_repo
baseurl=https://xxx/centos/$releasever/os/$basearch
gpgcheck=0
​
enable=1
​
[mysql]
name=mysql_repo
baseurl=https://xxx/mysql-repo/yum/mysql-5.7-community/el/$releasever/$basearch
​
gpgcheck=0
enable=1
​
[epel]
name=epel_repo
baseurl=https://xxx/epel/$releasever/$basearch
gpgcheck=0
enable=1
[percona]
name=percona_repo
baseurl = https://xxx/percona/release/$releasever/RPMS/$basearch
enabled = 1
gpgcheck = 0

 

awk '
    BEGIN{RS=""}# 按段落
    /\[ mysql\]/{       print;       while((getline)>0 ){         if(/\[.*\]/){           exit         }         print       } } ' a.txt

5.根据某字段去重

去掉uid=xxx重复的行。

2019-01-13_12:00_index?uid=123
2019-01-13_13:00_index?uid=123
2019-01-13_14:00_index?uid=333
2019-01-13_15:00_index?uid=9710
2019-01-14_12:00_index?uid=123
2019-01-14_13:00_index?uid=123
2019-01-15_14:00_index?uid=333
2019-01-16_15:00_index?uid=9710
首先利用uid去重,我们需要利用?进行划分,然后将uid=xxx保存在数组中,这是判断重复的依据
然后统计uid出现次数,第一次出现统计,第二次不统计
awk -F"?" '!arr[$2]++{print}' a.txt
awk -F"?" '{arr[$2]=arr[$2]+1;if(arr[$2]==1){print}}'
awk -F"?" '{arr[$2]++;if(arr[$2]==1){print}}'
结果:

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

 

6.次数统计

portmapper
portmapper
portmapper
portmapper
portmapper
portmapper
status
status
mountd
mountd
mountd
mountd
mountd
mountd
nfs
nfs
nfs_acl
nfs
nfs
nfs_acl
nlockmgr
nlockmgr
nlockmgr
nlockmgr
nlockmgr
awk '{arr[$0]++}END{OFS="\t";for(idx in arr){printf arr[idx],idx}}' a.txt
awk '{arr[$0]++}END{for(i in arr){print arr[i], i}}' index.txt

 

7.统计TCP连接状态数量

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

 

统计得到的结果:

5: LISTEN
2: ESTABLISHED
netstat -antp | awk '{arr[$6]++}END{for (i in arr){print arr[i], i}}'
netstat -antp | grep 'tcp' | awk '{print $6}' | sort | uniq -c

 

netstat -tnap |\
awk '   /^tcp/ {     arr[$6]++   }   END{     for(state in arr){       print arr[state] " : " state     }   }
'

 

一行式:

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

 

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

日志示例数据:

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

 

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

# 法一
awk '$9!=200{arr[$1]++}END{for(i in arr){print arr[i],i}}' access.log | sort -k1nr | head -n 10
​
# 法二:
awk中排序函数sort asort
设置排序顺序PROCINFO
PROCINFO["sorted_in"]=@val_num_desc
awk '
    $9!=200{arr[$1]++}
    END{
        PROCINFO["sorted_in"]="@val_num_desc";
        for(i in arr){
            #设置计数器
            if(cnt++==10){exit}
            print arr[i],i
        }
}' access.log

 

9.统计独立IP

? url 访问IP 访问时间 访问人

a.com.cn|202.109.134.23|2015-11-20 20:34:43|guest
b.com.cn|202.109.134.23|2015-11-20 20:34:48|guest
c.com.cn|202.109.134.24|2015-11-20 20:34:48|guest
a.com.cn|202.109.134.23|2015-11-20 20:34:43|guest
a.com.cn|202.109.134.24|2015-11-20 20:34:43|guest
b.com.cn|202.109.134.25|2015-11-20 20:34:48|guest

 

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

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

 

并且有三个对应的文件:

a.com.cn.txt
b.com.cn.txt
c.com.cn.txt

 

代码:

BEGIN{
  FS="|"
}
!arr[$1,$2]++{
  arr1[$1]++
}
END{   for(i in arr1 ){     print i, arr1[i] >(i".txt" )
  } }

10.处理字段缺失的数据

ID  name    gender  age  email          phone
1   Bob     male    28   [email protected]     18023394012
2   Alice   female  24   [email protected]  18084925203
3   Tony    male    21                  17048792503
4   Kevin   male    21   [email protected]    17023929033
5   Alex    male    18   [email protected]    18185904230
6   Andy    female       [email protected]    18923902352
7   Jerry   female  25   [email protected]  18785234906
8   Peter   male    20   [email protected]     17729348758
9   Steven          23   [email protected]    15947893212
10  Bruce   female  27   [email protected]   13942943905

 

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

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

将空白部分保留下来

awk '{print $0}' FIELDWIDTHS="2 2:6 2:6 2:3 2:13 2:11" a.txt
FIELDWIDTH第一个字段是字符宽度ID为2,指定2个字符宽度
第两个字段最大为6,但前面和ID之间还有两个空格,所以可以指定宽度为8,也可以跳过两个字符2:6
awk '{print $0}' FIELDWIDTHS="2 2:6 2:6 2:3 2:13 2:11" a.txt
awk 'NR==4{print $5}' FIELDWIDTHS="2 2:6 2:6 2:3 2:13 2:11" a.txt

 

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

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

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...中)。

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

 

12.取字段中指定字符数量

16  001agdcdafasd
16  002agdcxxxxxx
23  001adfadfahoh
23  001fsdadggggg

 

得到:

16  001
16  002
23  001
23  002
awk字符索引从1开始
awk '{print $1,substr($2,1,3)}'
利用FIELDWIDTH分割
awk 'BEGIN{FIELDWIDTHS="2 2:3"}{print $1,$2}' a.txt

 

13.行列转换

name age
alice 21
ryan 30

 

转换得到:

name alice ryan
第一行数据来源为第一列,而且跨行,我们需要利用数组保存起来
age 21 30
awk '
    {
      for(i=1;i<=NF;i++){
          arr[i]=arr[i]" "$i
      }
    }
    END{
        for(i=1;i<=NF;i++){
            print arr[i]
        }
    }
' a.txt

 

14.行列转换2

文件内容:

74683 1001
74683 1002
74683 1011
74684 1000
74684 1001
74684 1002
74685 1001
74685 1011
74686 1000
....
100085 1000
100085 1001

 

文件就两列,希望处理成

74683 1001 1002 1011
74684 1000 1001 1002
...

 

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

{
  if($1 in arr){
    arr[$1] = arr[$1]" "$2
  } else {
    arr[$1] = $2
  }
  
}
​
END{
  for(i in arr){
    printf "%s %s\n",i,arr[i]
  }
}

 

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

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

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

# 2019-11-10 03:42:40转换成epoch为1970-01-01 00:00:00
$ awk 'BEGIN{print mktime("2019 11 10 03 42 40")}'
1573328560

 

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

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

可以利用patsplit来取时间中的数字

BEGIN{
#要筛选什么时间的日志,将其时间构建成epoch值
which_time = mktime( "2019 11 10 03 42 40")
} { #取出日志中的日期时间字符串部分
match($0, "^.*\\[(.*)\\].* " , arr)
#将日期时间字符串转换为epoch值
tmp_time = strptime1 (arr[1])
#通过比较epoch值来比较时间大小 if(tmp_time > which_time){print}
}
#构建的时间字符串格式为: "2019-11-10T03∶42∶40+08:00"
function strptime1 (str  ,arr,Y,M,D,H,m,S){ patsplit(str,arr, "[0-9]{1,4}") Y=arr[1] M=arr[2]
D=arr[3]
H=arr[4]
m=arr[5]
S=arr[6] return mktime( sprintf("%s %s %s %s %s %s ",Y ,M,D,H,m,S))
}

 

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

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

 

16.去掉/**/中间的注释

示例数据:

/*AAAAAAAAAA*/
1111
222
​
/*aaaaaaaaa*/
32323
12341234
12134 /*bbbbbbbbbb*/ 132412
​
14534122
/*
    cccccccccc
*/
xxxxxx /*ddddddddddd
    cccccccccc
    eeeeeee
*/ yyyyyyyy
5642341

 

#注释内的行
/\/\*/{   #同行有"*/"
  if(/\*\// ){     print gensub( "(.*)/\\*.*\\*/(.*)”,"\\1\\2", "g" , $0)
}else {   #同行没有"*/“
  #1.去掉/*行后的内容   print gensub( "(.*)/\\*.*","\\l","g",$0)
  #2.继续读取,直到出现*/,并去掉中间的所有数据
  while( ( getline ) > 0 ){     #出现了*/行     if(/\*\//){       print gensub( ".*\\*/(.*)"," \\1","g",$0)     }    }   } } #非注释内容
!/\/\*/{print}

 

17.前后段落关系判断

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

2019-09-12 07:16:27 [-][
  'data' => [
    'http://192.168.100.20:2800/api/payment/i-order',
  ],
]
2019-09-12 07:16:27 [-][
  'data' => [
    false,
  ],
]
2019-09-21 07:16:27 [-][
  'data' => [
    'http://192.168.100.20:2800/api/payment/i-order',
  ],
]
2019-09-21 07:16:27 [-][
  'data' => [
    'http://192.168.100.20:2800/api/payment/i-user',
  ],
]
2019-09-17 18:34:37 [-][
  'data' => [
    false,
  ],
]
BEGIN{
  RS="]\n"
  ORS=RS
}
{
  if(/false/ && prev ~ /i-order/){
    print tmp
    print
  }
  tmp=$0
}

 

标签:实战,arr,00,案例,awk,print,2019,com
From: https://www.cnblogs.com/wxy1787880204/p/17609225.html

相关文章

  • Git实战指南:从入门到实战手把手教你玩转Git
    一、基本操作1.使用命令设置用户名:gitconfig--globaluser.name"你的用户名"2.使用命令设置邮箱:gitconfig--globaluser.email"你的邮箱"2-1.查看一下配置的【用户名】和【邮箱】,以防配置错误:3.使用命令生成SSHKey:ssh-keygen-trsa-C'你的邮箱'(这样代表以及生成成功了)4.......
  • Caddy 入门实战(1)--简介及安装
    Caddy是一款基于Go语言编写的强大且可扩展的平台,可以给你的站点、服务和应用程序提供服务。本文主要内容为Caddy的简介及安装,文中所使用到的软件版本:Caddy2.6.4、CentOS 7.9.2009。1、简介大多数人将Caddy用作Web服务器或代理,但Caddy的本质是诸多服务器的服务器。......
  • Git实战指南:从入门到实战手把手教你玩转Git
    一、基本操作1.使用命令设置用户名:gitconfig--globaluser.name"你的用户名"2.使用命令设置邮箱:gitconfig--globaluser.email"你的邮箱"2-1.查看一下配置的【用户名】和【邮箱】,以防配置错误:3.使用命令生成SSHKey:ssh-keygen-trsa-C'你的邮箱'(这样代......
  • Spring Boot&Vue3前后端分离实战wiki知识库系统<十一>--文档管理功能开发三
    文档内容的显示:在上一次SpringBoot&Vue3前后端分离实战wiki知识库系统<十>--文档管理功能开发二文档管理模块还差文档的显示木有完成,所以接下来先将这块模块给收尾了。增加单独获取内容的接口:概述:在前端页面文档查询时,只查询了文档的基本信息,其中文档的富文本内容是木有带出来的:当......
  • Spring Boot + Vue3前后端分离实战wiki知识库系统<十一>--文档管理功能开发三
    文档内容的显示:在上一次https://www.cnblogs.com/webor2006/p/17510360.html文档管理模块还差文档的显示木有完成,所以接下来先将这块模块给收尾了。增加单独获取内容的接口:概述:在前端页面文档查询时,只查询了文档的基本信息,其中文档的富文本内容是木有带出来的:当然也不可能......
  • 05服务拆分-案例Demo
    下载对应初始项目cloud-demo链接:https://pan.baidu.com/s/1NpovDVLj8ZSrDjt2seID2A?pwd=dp3f提取码:dp3f准备数据库dockerpsdockerexec-it6d542566d077/bin/bashpsql'host=localhostport=5432user=postgresdbname=postgres'createdatabasecloud_order;cre......
  • 简单的用Python获取一下视频弹幕,新手练手实战项目,非常简单!
    昨天看到个视频,弹幕挺有意思的,于是想着用Python给他全部扒下来。代码非常简单,接下来我们看看具体操作。需要准备这些软件Python3.8Pycharm模块使用importrequests数据请求importjieba分词importwordcloud词云importparsel数据解析importre......
  • 【腾讯云 Cloud Studio 实战训练营】一个多年云端开发体验者的实战使用
    背景近几年,越来越感觉软件的趋势逐渐从客户端越来越转向以web提供服务的云端,特别是互联网行业,典型的比如原型设计产品,从客户端软件Axure逐渐到墨刀在线原型设计的流行,UI设计行业photoshop&sketch转向蓝湖&MasterGo在线UI设计,web的力量前所未有的强大,可以说一个浏览器就能满足......
  • abp-vnext-pro 实战(四,给客户表增加多租户)
    XXXHttpApiHostModule里面默认启用多租户publicoverridevoidOnApplicationInitialization(ApplicationInitializationContextcontext){varapp=context.GetApplicationBuilder();。。。if(MultiTenancyConst......
  • 【用户案例】中国中纺集团:打造数字化发展新动能
    随着人工智能、大数据、互联网、机器人流程自动化(RPA)等技术的迅猛发展,数字化、智能化正逐渐引领新一轮全球生产力的革命,成为核心推动力。此外,新技术和新模式的层出不穷,给纺织业的业务带来了前所未有的新挑战。中纺集团,作为棉纺行业的佼佼者,始终肩负维护国家棉花产业安全的重任,并......