安全—04day

认识awk

awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入(stdin)、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。awk有很多内建的功能,比如数组、函数等,这是它和C语言的相同之处,灵活性是awk最大的优势。

awk常用命令选项

  • -F fs:fs指定输入分隔符,fs可以是字符串或正则表达式,如-F:
  • -v var=value:赋值一个用户定义变量,将外部变量传递给awk
  • -f scripfile:从脚本文件中读取awk命令

内置变量

  • FS输入字段分隔符,默认为空白字符
  • OFS输出字段分隔符,默认为空白字符
  • RS输入记录分隔符,指定输入时的换行符,原换行符仍有效
  • ORS输出记录分隔符,输出时用指定符号代替换行符
  • NF字段数量,共有多少字段, N F 引用最后一列, NF引用最后一列, NF引用最后一列,(NF-1)引用倒数第2列
  • NR行号,后可跟多个文件,第二个文件行号继续从第一个文件最后行号开始
  • FNR各文件分别计数, 行号,后跟一个文件和NR一样,跟多个文件,第二个文件行号从1开始
  • FILENAME当前文件名
  • ARGC命令行参数的个数
  • ARGV数组,保存的是命令行所给定的各参数,查看参数

awk的经典实战案例

一,插入几个新字段

在"I L You"的L后面插入3个字段ove

echo "I L You" | awk '{$2=$2"ove";print}'

在这里插入图片描述

二,格式化空白

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

[root@CentOS awk]# vim 1.txt 
      aaaa        bbb     ccc                 
   bbb     aaa ccc
ddd       fff             eee gg hh ii jj
awk '{$1=$1;print}' 1.txt
awk 'BEGIN{OFS="\t"}{$1=$1;print}' 1.txt

在这里插入图片描述

三,筛选IPv4地址

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

方法一:
ifconfig | awk '/inet / && ! ($2 ~ /^127/){print $2}'
ifconfig | awk '/inet / &&  ($2 ~ /^192/){print $2}'
方法二:
ifconfig | awk 'BEGIN{RS=""}!/lo/ {print $6}'
ifconfig | awk 'BEGIN{RS=""}/ens33/ {print $6}'

在这里插入图片描述

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

[root@CentOS ~]# vim 2.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
[root@CentOS ~]# vim 2.awk 
index($0,"[mysql]"){
        print
        while((getline var)>0){
                if(var ~ /\[.*\]/){
                        exit
                        }
                print var
                }
        }

在这里插入图片描述

五,根据某字段去重

[root@CentOS ~]# vim 3.txt
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
awk -F"?" '!arr[$2]++{print}' a.txt

在这里插入图片描述

六,次数统计

[root@CentOS ~]# vim 4.txt
ma
ma
ma
li
li
hua
hua
hua
hua
awk '{arr[$0]++}END{for(i in arr){print arr[i],i}}' 4.txt

在这里插入图片描述

七,统计TCP连接状态数量

[root@CentOS ~]# netstat -antp
Active Internet connections (servers and established)
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      908/sshd            
tcp        0     36 192.168.181.130:22      192.168.181.1:53944     ESTABLISHED 1364/sshd: root [pr 
tcp6       0      0 :::22                   :::*                    LISTEN      908/sshd            
tcp6       0      0 :::80                   :::*                    LISTEN      907/httpd    
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

在这里插入图片描述

八,统计日志中各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 '$8!=200{arr[$1]++}END{for(i in arr){print arr[i],i}}' access.log | sort -k1nr | head -n 10

# 法二:
awk '
    $8!=200{arr[$1]++}
    END{
        PROCINFO["sorted_in"]="@val_num_desc";
        for(i in arr){
            if(cnt++==10){exit}
            print arr[i],i
        }
}' access.log

九,统计独立IP

[root@CentOS ~]# cat 5.txt 
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

[root@CentOS ~]# cat 5.awk 
BEGIN{
	FS="|"
	}

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

在这里插入图片描述

十,处理字段缺失的数据

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

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

在这里插入图片描述

十一,取字段中指定字符数量

[root@CentOS ~]# cat 7.txt 
16  001agdcdafasd
16  002agdcxxxxxx
23  001adfadfahoh
23  001fsdadggggg

[root@CentOS ~]# awk '{print $1,substr($2,1,3)}' 7.txt 

在这里插入图片描述

十二,行列转换

[root@CentOS ~]# cat 8.txt 
name age
alice 21
ryan 30


[root@CentOS ~]# cat 8.awk 
{
      for(i=1;i<=NF;i++){
        if(!(i in arr)){
          arr[i]=$i
        } else {
            arr[i]=arr[i]" "$i
        }
      }
    }
    END{
        for(i=1;i<=NF;i++){
            print arr[i]
        }
}

在这里插入图片描述

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

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

[root@CentOS ~]# cat 10.txt 
BEGIN{
  # 要筛选什么时间的日志,将其时间构建成epoch值
  which_time = mktime("2023 01 31 16 00 00")a
}

{
  # 取出日志中的日期时间字符串部分
  match($0,"^.*\\[(.*)\\].*",arr)
  
  # 将日期时间字符串转换为epoch值
  tmp_time = strptime2(arr[1])
  
  # 通过比较epoch值来比较时间大小
  if(tmp_time > which_time){
    print $1
  }
}

# 构建的时间字符串格式为:"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]
}

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值