awk命令的基本使用

命令主要用法
  -格式1:前置命令 | awk [选项] '[条件]{编辑指令}'
  -格式2:awk [选项] '[条件]{编辑指令}' filename

常用命令选项
  -F:指定分隔符,可省略(默认空格或者Tab位)
  -f:调用awk脚本尽心个处理
  -V:调用外部shell变量

内置变量
  变量       用途
  FS        保存或设置字段分隔符,如FS=":"
  $n        指定分隔的第n个字段,例如$1,$4分别表示第1例,第4例
  $0        当前读入的整行文本内容
  NF        记录当前处理行的字段个数(有多少列)
  FNR        记录当前处理行在原文本内的行号
  NR        记录当前已经读入行的数量(多个文本一起读取时,行数累加)
  FILENAME  当前处理的文件名
  ENVIRON   调用shell环境变量,格式:ENVIRON["变量名"]

awk过滤的时机
  BEGIN{}
    读入第一行文本之前执行
    一般用来初始化操作
  逐行处理{}
    逐行读入文本执行相应的处理
    是最常见,用得最多的编辑指令块

  END{}
    处理完最后一行文本后执行
    一般用来统计或处理结果
    

[root@localhost ~]# awk '{print "第" FNR"行" ,"有"NF"列"}' a.txt 
第1行 有2列
第2行 有4列
第3行 有2列
第4行 有3列

   

  截取字符串前后字符

//截取007之前的字符串
[root@pgslave ~]# echo linyouyi007henshuai  | awk -F '007' '{print $1}'
linyouyi
//截取007之前的加上007本身
[root@pgslave ~]# echo linyouyi007henshuai  | awk -F '007' '{print $1 FS}'
linyouyi007
//截取以007分隔符第二列
[root@pgslave ~]# echo linyouyi007henshuai  | awk -F '007' '{print $2}'
henshuai
//截取以007分隔符,输出包含007本身及第二列
[root@pgslave ~]# echo linyouyi007henshuai  | awk -F '007' '{print FS $2}'
007henshuai

1)输出当前用户的UID

[root@localhost ~]# awk -F: '$1==ENVIRON["USER"]{print $3}' /etc/passwd
0

 2)预处理

[root@localhost ~]# awk 'BEGIN{a=10;print a+10}'
20

3)统计使用bash的用户数量

[root@localhost ~]# awk 'BEGIN{x=0}/<bash$/{x++}END{print x}' /etc/passwd
1

awk处理条件概述
  格式
    awk [选项] '[条件]{指令}' filename
  条件的表现形式
    正则表达式
      /正则内容/
      ~匹配,!~不匹配
    数值/字符串比较
      ==,!=,>=,<=,>,<等
    逻辑比较
      &&逻辑与:期望多条件都成立
      ||逻辑或:只要有一个条件成立即满足要求
    运算符
      -,+,*,/,%,++,--,+=,-=,*=,/=

1)正则内容

[root@localhost ~]# awk -F: '/^root/{print}' /etc/passwd
root:x:0:0:root:/root:/bin/bash

2)~匹配,!~不匹配

[root@localhost ~]# awk -F: '$7!~/nologin/{print}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt

3)==,!=,>=,<=,>,<等,输出第二行文本

[root@localhost ~]# awk 'NR==2{print}' /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin

4)&&逻辑与:期望多条件都成立

[root@localhost ~]# awk -F: '$3>=0&&$3<=10{print $1,$3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
uucp 10

5)运算符,统计文本总字段数量

[root@localhost ~]# awk -F: 'BEGIN{i=0}{i+=NF}END{print i}' /etc/passwd
140

awk流程控制
  单分支
    if(条件){指令}
  双分支
    if(条件){指令}else{指令}
  多分支
    if(条件){指令}else if{指令}else{指令}

  while循环
    while(条件){指令}
  do while
    do{指令}while(条件)

  for循环
    for(初始值;条件;步长){指令}

1)统计UID小于或等于500的用户个数

[root@localhost ~]# awk -F: 'BEGIN{i=0;j=0}{if($3<=500){i++}else{j++}}END{print i,j}' /etc/passwd
21 1

 2)统计root出现次数

[root@localhost ~]# awk -F[:/] '{i=1}{while(i<=NF){if($i~/root/){j++};i++}}END{print j}' /etc/passwd
4

3)for循环

[root@localhost ~]# awk 'BEGIN{for(i=0;i<=10;i++){print i}}'
0
1
2
3
4
5
6
7
8
9
10

数组
  定义数组
    格式:数组名[下标]=元素值
  调用数组
    格式:数组名[下标]
  遍历数组
    用法:for(变量 in 数组名){print 数组名[变量]}
  数组的经典使用
    去除文本重复行:awk '!a[$2]++{print $2}' filename
    逐行分析,遇到重复行就跳过

1)去重

[root@localhost ~]# cat a.txt 
111 111
222222  22 2222  2
333333333 33
444444444444 444    44
444444444444 444    44
[root@localhost ~]# awk '!a[$2]++{print $2}' a.txt
111
22
33
444

2)列出用户登陆shell的种类

[root@localhost ~]# awk -F: '!shell[$7]++{print $7}' /etc/passwd
/bin/bash
/sbin/nologin
/bin/sync
/sbin/shutdown
/sbin/halt

3)列出用户登陆shell的种类及个数,类似的可以统计web访问ip及访问次数

[root@localhost ~]# awk -F: '{shell[$7]++}END{for(i in shell){print i,shell[i]}}' /etc/passwd
/bin/sync 1
/bin/bash 3
/sbin/nologin 16
/sbin/halt 1
/sbin/shutdown 1
[root@localhost ~]# awk -F: '{shell[$7]++}END{for(i in shell){print i,shell[i]}}' /etc/passwd | sort -nr -k2
/sbin/nologin 16
/bin/bash 3
/sbin/shutdown 1
/sbin/halt 1
/bin/sync 1

 4)统计nginx访问最多的ip

[root@001 nginx]$ sudo awk '{ip[$1]++}END{for(i in ip) {print i,ip[i]}}' access.log | sort -nr -k2
146.145.196.170 3974
111.7.10.21 15
124.25.17.151 11
47.92.114.243 9
11.7.100.24 9
111.7.100.22 8
111.7.100.20 8
106.14.217.247 8
47.92.126.167 7
11.7.100.23 7
111.7.10.19 7
111.7.100.25 6
111.7.10.18 5
111.7.100.27 4
111.7.10.26 3
80.82.70.187 2
83.143.86.62 1
80.82.78.104 1

 以上命令似乎无法统计大文件

统计某个端口的连接数量

[root@iZ8vb4d961fcjtctipquxtZ agnss]# netstat -an | awk '{print $4}' | awk -F":" '{ip[$2]++}END{for(i in ip) {print i,ip[i]}}' | sort -nr -k2 | head -20
9011 415
8012 66
8011 19
9013 4
8888 3
9999 2
9012 2
22 2
9998 1
9113 1
9112 1
9111 1
8887 1
8113 1
8112 1
8111 1
8013 1
7808 1
68 1
50128 1

统计并排序ip连接数

[root@iZ8vb4d961fcjtctipquxtZ agnss]# netstat -an | awk '{print $5}' | awk -F":" '{ip[$1]++}END{for(i in ip) {print i,ip[i]}}' | sort -nr -k2 | head -20
STREAM 64
] 24
0.0.0.0 21
DGRAM 14
42.123.126.84 10
42.123.126.83 10
223.104.24.141 7
223.104.22.234 6
58.220.220.108 3
39.144.41.89 3
192.200.110.242 3
190.63.239.253 3
223.104.24.171 2
200.68.159.110 2
200.68.158.87 2
200.68.158.80 2
200.68.158.36 2
200.68.158.112 2
200.68.140.83 2
200.68.140.44 2

统计各个连接状态数量

[root@iZ8vb4d961fcjtctipquxuZ agnss]# netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' 
LAST_ACK 12
SYN_RECV 19
ESTABLISHED 101
FIN_WAIT1 33
FIN_WAIT2 16
CLOSING 5
TIME_WAIT 273
原文地址:https://www.cnblogs.com/linyouyi/p/9769163.html