shell之awk技术

awk概述

  • awk处理文本和数据的方式是这样,他逐行扫描文件,从第1行到最后一行,寻找匹配的特定模式的行,并在这些行上进行你想要的操作 (这里与sed一样),如果没有指定处理动作,则把匹配的行显示到标准输出(屏幕)上;如果没有指定模式,则所有被操作所指定的行都被处理;gawk是awk的GUN版本。

    语法格式

1
2
3
4
5
# options:-F:定义输入字段分隔符,默认的分隔符是空格或者制表符(tab)
# commands:BEGIN{} {} END{}
# 行处理前 行处理 行处理后
# BEGIN{}通常用于定义一些变量,eg:输入时,修改字段分隔符FS=":",输出结果时,按照OFS="---"分割
awk [options] 'commands' filenames
  • eg:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    [root@centos7 shell]# cat passwd
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    halt:x:7:0:halt:/sbin:/sbin/halt
    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    operator:x:11:0:operator:/root:/sbin/nologin
    games:x:12:100:games:/usr/games:/sbin/nologin
    ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
    nobody:x:99:99:Nobody:/:/sbin/nologin
    systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
    dbus:x:81:81:System message bus:/:/sbin/nologin
    polkitd:x:999:998:User for polkitd:/:/sbin/nologin

    [root@centos7 shell]# awk 'BEGIN{FS=":";OFS="---"} {print $1,$2}' passwd
    root---x
    bin---x
    daemon---x
    halt---x
    mail---x
    operator---x
    games---x
    ftp---x
    nobody---x
    systemd-network---x
    dbus---x
    polkitd---x

    [root@centos7 shell]# awk 'BEGIN{print 2/5} {print "ok"} END{print "----"}' passwd
    0.4
    ok
    ok
    ok
    ok
    ok
    ok
    ok
    ok
    ok
    ok
    ok
    ok
    ----

    [root@centos7 shell]# awk '{print $1}' passwd # 打印第一列,默认以空格和tab分割
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    halt:x:7:0:halt:/sbin:/sbin/halt
    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    operator:x:11:0:operator:/root:/sbin/nologin
    games:x:12:100:games:/usr/games:/sbin/nologin
    ftp:x:14:50:FTP
    nobody:x:99:99:Nobody:/:/sbin/nologin
    systemd-network:x:192:192:systemd
    dbus:x:81:81:System
    polkitd:x:999:998:User

    [root@centos7 shell]# awk -F ":" '{print $1}' passwd # 打印第一列,设置以:分割,或写成awk 'BEGIN{FS=":"} {print $1}' passwd
    root
    bin
    daemon
    halt
    mail
    operator
    games
    ftp
    nobody
    systemd-network
    dbus
    polkitd

awk命令格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# awk 'pattern' filename,pattern类似正则
[root@centos7 shell]# awk '/root/' passwd # 匹配出现root的行
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

# awk '{action}' filename
[root@centos7 shell]# awk -F: '{print $1}' passwd
root
bin
daemon
halt
mail
operator
games
ftp
nobody
systemd-network
dbus
polkitd

# awk 'pattern {action}' filename
[root@centos7 shell]# awk 'BEGIN{FS=":"} /root/{print $1 $2}' passwd
rootx
operatorx

# command |awk 'pattern {action}'
[root@centos7 shell]# df -P
文件系统 1024-块 已用 可用 配额 挂载点
/dev/sda3 17410832 5316368 11186996 33% /
devtmpfs 998436 0 998436 0% /dev
tmpfs 1014044 0 1014044 0% /dev/shm
tmpfs 1014044 10420 1003624 2% /run
tmpfs 1014044 0 1014044 0% /sys/fs/cgroup
/dev/sda1 999320 136208 794300 15% /boot
tmpfs 202812 12 202800 1% /run/user/42
tmpfs 202812 0 202812 0% /run/user/0
[root@centos7 shell]# df -P |grep '/' |awk '$4>23000 {print $4}'
11186996
998436
1014044
1003624
1014044
794300
202800
202812

awk原理

  • awk -F: '{print $1,$3}' passwd为例:
    • ①awk使用一行作为输入,并捋这一行赋给内部变量$0,每一行也可称为一个记录,以换行符结束。
    • ②然后,行被’:’(默认为空格或制表符)分解成字段(或域),每个字段存储在已编号的变量中,从$1开始,最多达100个字段。
    • ③awk如何知道用空格来分隔字段的呢?因为有一个内部变量FS来确定字段分隔符。初始时,FS赋为空格。
    • ④awk打印字段时,将以设置的方法使用print函数打印,awk在打印的字段间加上空格,因为$1,$3之间有一个逗号。逗号比较特殊,它映射为另一个内部变量,称为输出字段分隔符OFS,OFS默认为空格。
    • ⑤awk输出之后,将从文件中获取另一行,并将其存储在$0中,覆盖原来的内容,然后将新的字符串分隔成字段并进行处理。该过程将持续到所有行处理完毕。

记录与字段相关的内部变量(man awk)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
[root@centos7 shell]# cat hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
1111
1111
[root@centos7 shell]# cat passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin

[root@centos7 shell]# awk -F : '{print $1}' passwd
root
bin
daemon
halt
mail
operator
games
ftp
nobody
systemd-network
dbus
polkitd

[root@centos7 shell]# awk -F ":" '{print NR,$1}' passwd hosts # NR:打印总行号
1 root
2 bin
3 daemon
4 halt
5 mail
6 operator
7 games
8 ftp
9 nobody
10 systemd-network
11 dbus
12 polkitd
13 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
14
15 1111
16 1111

[root@centos7 shell]# awk -F : '{print FNR, $1}' passwd hosts # FNR:打印当前文件的行号
1 root
2 bin
3 daemon
4 halt
5 mail
6 operator
7 games
8 ftp
9 nobody
10 systemd-network
11 dbus
12 polkitd
1 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
2
3 1111
4 1111

[root@centos7 shell]# awk -F ":" '{print FNR,$0,NF}' hosts # NF指的是最后一列的下标
1 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 1
2 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 3
3 1111 1
4 1111 1

# FS:输入字段分隔符,默认空格
[root@centos7 shell]# awk -F: '/root/{print $1,$3}' passwd
root 0
operator 11
[root@centos7 shell]# awk -F "[ :\t]" '{print $1,$2,$3}' passwd
root x 0
bin x 1
daemon x 2
halt x 7
mail x 8
operator x 11
games x 12
ftp x 14
nobody x 99
systemd-network x 192
dbus x 81
polkitd x 999
[root@centos7 shell]# awk 'BEGIN{FS=":"} {print $1,$3}' passwd
root 0
bin 1
daemon 2
halt 7
mail 8
operator 11
games 12
ftp 14
nobody 99
systemd-network 192
dbus 81
polkitd 999

# OFS:输出字段分隔符
[root@centos7 shell]# awk -F ":" 'BEGIN{OFS=":"} {print $1,$3}' passwd
root:0
bin:1
daemon:2
halt:7
mail:8
operator:11
games:12
ftp:14
nobody:99
systemd-network:192
dbus:81
polkitd:999

[root@centos7 shell]# awk 'BEGIN{FS=":";OFS="+++"} /^root/{print $1,$2}' passwd
root+++x

# 记录分隔符RS和ORS(默认为换行符)
centos7 shell]# awk -F ":" 'BEGIN{ORS=" "} {print $0}' passwd
root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin polkitd:x:999:998:User for polkitd:/:/sbin/nologin
[root@centos7 shell]# awk -F ":" 'BEGIN{RS="bash"} {print $0}' passwd
root:x:0:0:root:/root:/bin/

bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin

[root@centos7 shell]#

[root@centos7 shell]# cat test.txt
11 22 33 44:55:66
[root@centos7 shell]# awk -F ":" 'BEGIN{RS=" "} {print $0}' test.txt
11
22
33
44:55:66

[root@centos7 shell]#

awk的格式化输出

  • print函数。

    1
    2
    3
    [root@centos7 shell]# date |awk '{print "Month: "$2"\nYear: "$NF}'
    Month: 08月
    Year: CST
  • printf函数:精确控制输出格式。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    # %s字符类型
    # %d数值类型
    # %f浮点类型
    # '-'表示左对齐。默认是右对齐
    # printf默认不会在行尾自动换行
    [root@centos7 shell]# awk -F ":" '{printf "%-20s %-20s %-25s\n",$1,$2,$3}' passwd # %-20s:表示第1个字段占20个字符,-表示左对齐,s表示字符串
    root x 0
    bin x 1
    daemon x 2
    halt x 7
    mail x 8
    operator x 11
    games x 12
    ftp x 14
    nobody x 99
    systemd-network x 192
    dbus x 81
    polkitd x 999

awk模式和动作

  • 任何awk语句都由模式和动作组成。模式部分决定动作语句何时触发及触发事件。处理即对数据进行的操作。如果省略模式部分,动作将时刻保持执行状态。模式可以是任何条件语句或者复合语句或者正则表达式。模式包括2个特殊字段BEGIN和END,使用BEGIN语句设置计数和打印头。BEGIN语句使用在任何文本浏览动作之前,之后文本浏览动作依据输入文本开始执行。
    END语句用来在awk完成文本浏览动作后,打印输出文本总数和结尾状态。

  • 模式可以是:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    # $0表示整行,~表示正则匹配,!表示不匹配
    [root@centos7 shell]# cat passwd
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    halt:x:7:0:halt:/sbin:/sbin/halt
    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    operator:x:11:0:operator:/root:/sbin/nologin
    games:x:12:100:games:/usr/games:/sbin/nologin
    ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
    nobody:x:99:99:Nobody:/:/sbin/nologin
    systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
    dbus:x:81:81:System message bus:/:/sbin/nologin
    polkitd:x:999:998:User for polkitd:/:/sbin/nologin

    [root@centos7 shell]# awk '/^root/' passwd # 等价于awk '$0 ~ /^root/' passwd
    root:x:0:0:root:/root:/bin/bash

    [root@centos7 shell]# awk '!/root/' passwd
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    halt:x:7:0:halt:/sbin:/sbin/halt
    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    games:x:12:100:games:/usr/games:/sbin/nologin
    ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
    nobody:x:99:99:Nobody:/:/sbin/nologin
    systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
    dbus:x:81:81:System message bus:/:/sbin/nologin
    polkitd:x:999:998:User for polkitd:/:/sbin/nologin

    # 匹配字段:匹配操作符~,!~
    [root@centos7 shell]# awk -F: '$1 ~ /^root/' passwd
    root:x:0:0:root:/root:/bin/bash

    [root@centos7 shell]# awk -F: '$1 !~ /^root/' passwd
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    halt:x:7:0:halt:/sbin:/sbin/halt
    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    operator:x:11:0:operator:/root:/sbin/nologin
    games:x:12:100:games:/usr/games:/sbin/nologin
    ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
    nobody:x:99:99:Nobody:/:/sbin/nologin
    systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
    dbus:x:81:81:System message bus:/:/sbin/nologin
    polkitd:x:999:998:User for polkitd:/:/sbin/nologin

    [root@centos7 shell]# awk -F: '$NF !~ /bash$/' passwd
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    halt:x:7:0:halt:/sbin:/sbin/halt
    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    operator:x:11:0:operator:/root:/sbin/nologin
    games:x:12:100:games:/usr/games:/sbin/nologin
    ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
    nobody:x:99:99:Nobody:/:/sbin/nologin
    systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
    dbus:x:81:81:System message bus:/:/sbin/nologin
    polkitd:x:999:998:User for polkitd:/:/sbin/nologin

awk比较表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
awk -F: '$3 == 0' /etc/passwd
awk -F: '$3 < 10' /etc/passwd
awk -F: '$NF == "/bin/bash"' passwd # 字符串匹配,要完全一样
awk -F: '$1 ~ /alic/' /etc/passwd # 模式匹配,可以匹配alice,alices

# 条件表达式
awk -F: '{if(){}}' /etc/passwd
awk -F: '{if(){} else{}}' /etc/passwd
# 大于300的打印整行
awk -F: '{if($3>300){print $0}}' passwd
awk -F: '{if($3>300){print $3} else{print $1}}'

# 算数运算:可以在模式中执行计算,awk都将按照浮点数方式执行算数运算
awk -F: '{if($3*10 > 500){print $0}}' passwd

# 逻辑操作符和复合模式
# && 逻辑与
# || 逻辑或
# ! 逻辑非
awk -F: '$1~/root/ && $3<=15' passwd
awk -F: '$1~/root/ || $3<=15' passwd

# 范围模式:从哪到哪
awk '/Tom/,/Suzanne/' filename
  • eg:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    awk '/west/' datafile		# 匹配west
    awk '/^north/' datafile # 匹配north开头
    awk '$3 ~ /^north/' datafile # $3匹配不是以north开头的
    awk '/^(no|so)/' datafile # 打印整行以no或者so开头的
    awk '{print $3,$2}' datafile
    awk '{print $3 $2}' datafile

    awk '{print $0}' /etc/passwd
    awk '{print "Number of fields:"NF}' /etc/passwd
    awk '/northeast/{print $3,$2}' datafile # 满足northeast才打印
    awk '/E/' datafile # 只要带有E就打印

    awk '/^[ns]/{print $1}' datafie # 以n或者s开头才打印
    awk '$5 ~ /\.[7-9]+/' datafile # 匹配.7到9的1到多个
    awk '$2 !~ /E/{print $1,$2}' datafile # $2不匹配E,才打印
    awk '$3 ~ /^Joel/{print $3 "is anice boy."}' datafile # $3匹配/^Joel/才打印
    awk '$8 ~ /[0-9][0-9]$/{print $8}' datafile # /[0-9][0-9]$/表示以数字结尾

    awk '$4 ~ /Chin$/{print "The price is $" $8 "."}' datafile # 匹配Chin结尾的才print,$8代表第8列
    awk '/Tj/{print $0}' datafile # 匹配Tj才打印

    awk '$7 == 5' datafile
    awk '$2 == "CT" {print $1,$2}' datafile
    awk '$7 != 5' datafile

awk脚本编程

  • 条件判断。

    1
    2
    3
    4
    5
    6
    7
    8
    # {if(表达式){语句;语句;......}}
    awk -F: '{if($3>0 && $3<1000){i++}} END{print i}' /etc/passwd # 统计系统用户数

    # {if(表达式){语句} else{语句}}
    awk -F: '{if($3==0){count++} else{i++}} END{print "管理员个数:"count;print "系统用户数:"i}}' /etc/passwd

    # {if(表达式){语句} else if(表达式){语句} else if(表达式){语句} else {语句}}
    awk -F: '{if($3==0){i++} else if($3>999){k++} else{j++}} END{print i;print k;print j}}' /etc/passwd
  • 循环。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    [root@centos7 shell]# awk 'BEGIN{i=1;while(i<=10){print i;i++}}' 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    [root@centos7 shell]# awk -F: '/^root/{i=1;while(i<=7){print $i;i++}}' passwd
    root
    x
    0
    0
    root
    /root
    /bin/bash

    # abc.txt文件内容:
    # 111 222
    # 333 444 555
    # 666 777 888 999
    [root@centos7 shell]# awk '{i=1;while(i<=NF){print $i;i++}} END{print "\n"}' abc.txt # print会换行
    111
    222
    333
    444
    555
    666
    777
    888
    999


    [root@centos7 shell]#

awk数组

  • awk不区分普通数组或者关联数组。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    [root@centos7 shell]# cat passwd
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    halt:x:7:0:halt:/sbin:/sbin/halt
    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    operator:x:11:0:operator:/root:/sbin/nologin
    games:x:12:100:games:/usr/games:/sbin/nologin
    ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
    nobody:x:99:99:Nobody:/:/sbin/nologin
    systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
    dbus:x:81:81:System message bus:/:/sbin/nologin
    polkitd:x:999:998:User for polkitd:/:/sbin/nologin

    # i从1开始
    [root@centos7 shell]# awk -F: '{username[++i]=$1} END{print username[1]}' passwd
    root

    # 数组遍历:按照下标遍历
    # 将需要统计的内容(某1字段)作为数组的索引,然后++即可
    [root@centos7 shell]# awk -F: '{user[j++]=$1} END{for(i in user){print i,user[i]}}' passwd
    4 mail
    5 operator
    6 games
    7 ftp
    8 nobody
    9 systemd-network
    10 dbus
    11 polkitd
    0 root
    1 bin
    2 daemon
    3 halt

    [root@centos7 shell]# awk -F: '{shells[$NF]++} END{for(i in shells){print i,shells[i]}}' passwd # 统计passwd中各种类型shell的数量
    /bin/bash 1
    /sbin/nologin 10
    /sbin/halt 1

    [root@centos7 shell]# netstat -ant |grep ':80' |awk '{status[$NF]++} END{for(i in status){print i,status[i]}}'

    [root@centos7 shell]# ss -an |grep ':80' |awk '{status[$2]++} END{for(i in status){print i,status[i]}}'

    [root@centos7 shell]# netstat -ant |grep ':80' |awk '{status[$NF]++} END{for(i in status){print i,status[i]}}' |sort -k2 -n |head

    [root@centos7 shell]# ss -ant|grep ':80' |awk -F "[ :]*" '{ips[$(NF-2)]++} END{for(i in ips){print i,ips[i]}}' |sort -k2 -rn |head -5 # 统计当前访问的每个IP的数量

awk的变量,内置函数及外部变量

  • 内置函数length:求出字符串长度。

    1
    2
    3
    4
    5
    6
    [root@centos7 shell]# awk -F: 'length($1)==4{count++;print $1} END{print "count is:"count}' passwd
    root
    halt
    mail
    dbus
    count is:4
  • 内置函数:sub()查找替换(只找第一个),gsub类似于sed中的g(全局找)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    [root@centos7 shell]# var="bash"
    # 方法一:在双引号的情况下使用
    [root@centos7 shell]# echo "unix script" |awk "gsub(/unix/,\"$var\")"
    bash script

    # 方法二:在单引号的情况下使用
    [root@centos7 shell]# echo "unix script" |awk 'gsub(/unix/,"'"$var"'")'
    bash script

    # 使用三引号
    [root@centos7 shell]# i=10
    [root@centos7 shell]# df -h |awk '{if((int($5)>'''$i''')){print $6":"$5}}'
    /:33%
    /boot:15%
    [root@centos7 shell]# df -h
    文件系统 容量 已用 可用 已用% 挂载点
    /dev/sda3 17G 5.1G 11G 33% /
    devtmpfs 976M 0 976M 0% /dev
    tmpfs 991M 0 991M 0% /dev/shm
    tmpfs 991M 11M 981M 2% /run
    tmpfs 991M 0 991M 0% /sys/fs/cgroup
    /dev/sda1 976M 134M 776M 15% /boot
    tmpfs 199M 12K 199M 1% /run/user/42
    tmpfs 199M 0 199M 0% /run/user/0
  • 内置函数:int。

    1
    2
    3
    [root@centos7 shell]# df -h |awk '{if((int($5)>5)){print $6":"$5}}'
    /:33%
    /boot:15%
  • 外部变量的使用,-v选项。

    1
    2
    [root@centos7 shell]# echo "unix script" |awk -v var="bash" 'gsub(/unix/,var)'
    bash script