随堂练习 文本处理三剑客 AWK

Posted xuanlv-0413

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了随堂练习 文本处理三剑客 AWK相关的知识,希望对你有一定的参考价值。

动作 printf

printf 可以实现格式化输出
格式:

printf “FORMAT”, item1, item2, ...

说明:
  必须指定FORMAT

  不会自动换行,需要显式给出换行控制符

  FORMAT中需要分别为后面每个item指定格式符

格式符:与item一一对应

%c:显示字符的ASCII码

%d, %i:显示十进制整数

%e, %E:显示科学计数法数值

%f:显示为浮点数

%g, %G:以科学计数法或浮点形式显示数值

%s:显示字符串

%u:无符号整数

%%:显示%自身

修饰符

#[.#] 第一个数字控制显示的宽度;第二个#表示小数点后精度,如:%3.1f

- 左对齐(默认右对齐) 如:%-15s

+ 显示数值的正负符号 如:%+d

范例:

awk -F: ‘{printf "%s",$1}‘ /etc/passwd

awk -F: ‘{printf "%s ",$1}‘ /etc/passwd

awk -F: ‘{printf "%20s ",$1}‘ /etc/passwd

awk -F: ‘{printf "%-20s ",$1}‘ /etc/passwd

awk -F: ‘{printf "%-20s %10d ",$1,$3}‘ /etc/passwd

awk -F: ‘{printf "Username: %s ",$1}‘ /etc/passwd

awk -F: ‘{printf “Username: %sUID:%d ",$1,$3}‘ /etc/passwd

awk -F: ‘{printf "Username: %25sUID:%d ",$1,$3}‘ /etc/passwd

awk -F: ‘{printf "Username: %-25sUID:%d ",$1,$3}‘ /etc/passwd

 操作符
算术操作符:

x+y, x-y, x*y, x/y, x^y, x%y

-x:转换为负数

+x:将字符串转换为数值

字符串操作符:没有符号的操作符,字符串连接
赋值操作符:

=, +=, -=, *=, /=, %=, ^=,++, --

范例:

[root@centos8 ~]# awk ‘BEGIN{i=0;print i++,i}‘
0 1

[root@centos8 ~]# awk ‘BEGIN{i=0;print ++i,i}‘
1 1

范例:

[root@centos8 ~]# awk -v n=0 ‘!n++‘ /etc/passwd
root:x:0:0:root:/root:/bin/bash

[root@centos8 ~]# awk -v n=0 ‘!n++{print n}‘ /etc/passwd
1

[root@centos8 ~]# awk -v n=1 ‘!n++{print n}‘ /etc/passwd

[root@centos8 ~]# awk -v n=0 ‘!++n{print n}‘ /etc/passwd

[root@centos8 ~]# awk -v n=0 ‘!++n‘ /etc/passwd

[root@centos8 ~]# awk -v n=-1 ‘!++n‘ /etc/passwd
root:x:0:0:root:/root:/bin/bash

比较操作符:

==, !=, >, >=, <, <=

范例:

[root@centos8 ~]# awk ‘NR==2‘ /etc/issue
Kernel on an m

[root@centos8 ~]# awk -F: ‘$3>=1000‘ /etc/passwd
nobody:x:65534:65534:Kernel Overflow User:/:/sbin/nologin
wang:x:1000:1000:wang:/home/wang:/bin/bash
long:x:1001:1001::/home/long:/bin/bash

范例:取奇,偶数行

[root@centos8 ~]# seq 10 | awk  ‘NR%2==0‘

2
4
6
8
10

[root@centos8 ~]# seq 10 | awk ‘NR%2==1‘
1
3
5
7
9

[root@centos8 ~]# seq 10 | awk ‘NR%2!=0‘
1
3
5
7
9

模式匹配符:

~ 左边是否和右边匹配,包含关系

!~ 是否不匹配

范例:

[root@centos8 ~]# awk -F: ‘$0 ~ /root/{print $1}‘ /etc/passwd

[root@centos8 ~]# awk -F: ‘$0 ~ "^root"{print $1}‘ /etc/passwd

[root@centos8 ~]# awk ‘$0 !~ /root/‘ /etc/passwd

[root@centos8 ~]# awk ‘/root/‘ /etc/passwd

[root@centos8 ~]# awk -F: ‘$3==0‘ /etc/passwd

[root@centos8 ~]# df | awk -F"[[:space:]]+|%" ‘$0 ~ /^/dev/sd/{print $5}‘
5
1
92

[root@centos8 ~]# ifconfig eth0 | awk ‘NR==2{print $2}‘
10.0.0.100

逻辑操作符:

与:&&,并且关系

或:||,或者关系

非:!,取反

范例:!取反

[root@centos8 ~]# awk ‘BEGIN{print i}‘

[root@centos8 ~]# awk ‘BEGIN{print !i}‘

1

[root@centos8 ~]# awk -v i=10 ‘BEGIN{print !i}‘

0

[root@centos8 ~]# awk -v i=3 ‘BEGIN{print !i}‘

0

[root@centos8 ~]# awk -v i=0 ‘BEGIN{print !i}‘

1

[root@centos8 ~]# awk -v i=abc ‘BEGIN{print !i}‘

0

[root@centos8 ~]# awk -v i=" " ‘BEGIN{print !i}‘

1

范例

awk -F:  ‘$3>=0 && $3<=1000 {print $1,$3}‘  /etc/passwd

awk -F:  ‘$3==0 || $3>=1000 {print $1,$3}‘  /etc/passwd

awk -F:  ‘!($3>=500) {print $1,$3}‘  /etc/paswd

awk -F:   ‘!($3>=500) {print $1,$3}‘  /etc/paswd

条件表达式(三目表达式)

selector?if-true-expression:if-false-expression

范例

awk -F: ‘{$3>=1000?usertype="Common User":usertype="Sysuser" ;printf "%-20s:%12s ",$1,usertype}‘  /etc/passwd

  模式PATTERN
PATTERN:根据pattern条件,过滤匹配的行,再做处理

1. 如果未指定:空模式,匹配每一行
范例:

[root@centos8 ~]# awk -F: ‘{print $1,$3}‘ /etc/passwd

2. /regular expression/:仅处理能够模式匹配到的行,需要用/ /括起来
范例:

[root@centos8 ~]# awk ‘/^UUID/{print $1}‘ /etc/fstab

[root@centos8 ~]# awk ‘!/^UUID/{print $1}‘ /etc/fstab

[root@centos8 ~]# df | awk ‘/^/dev/sd/‘
/dev/sda2 104806400 4935924 99870476 5% /
/dev/sda3 52403200 398876 52004324 1% /data
/dev/sda1 999320 848572 81936 92% /boot

3. relational expression: 关系表达式,结果为“真”才会被处理
真:结果为非0值,非空字符串

假:结果为空字符串或0值

范例:

[root@centos8 ~]# awk ‘!1‘ /etc/passwd

[root@centos8 ~]# awk ‘!0‘ /etc/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
adm:x:3:4:adm:/var/adm:/sbin/nologin
.......
[root@centos8 ~]# awk ‘1‘ /etc/issue
S
Kernel on an m

[root@centos8 ~]# awk ‘0‘ /etc/issue

[root@centos8 ~]# awk ‘"longwang"‘ /etc/issue
S
Kernel on an m
[root@centos8 ~]# awk ‘""‘ /etc/issue

[root@centos8 ~]# awk ‘longwang‘ /etc/issue

[root@centos8 ~]# awk ‘longwang‘ /etc/issue

[root@centos8 ~]# awk -v longwang=wang ‘longwang‘ /etc/issue
S
Kernel on an m

[root@centos8 ~]# awk -v longwang="" ‘longwang‘ /etc/issue

[root@centos8 ~]# awk -v longwang="0" ‘longwang‘ /etc/issue

[root@centos8 ~]# awk -v longwang=0 ‘longwang‘ /etc/issue

[root@centos8 ~]# awk ‘"0"‘ /etc/issue
S
Kernel on an m

[root@centos8 ~]# awk ‘0‘ /etc/issue

范例

awk -F:  ‘i=1;j=1{print i,j}‘  /etc/passwd

awk -F: ‘$3>=1000{print $1,$3}‘ /etc/passwd

awk -F: ‘$3<1000{print $1,$3}‘ /etc/passwd

awk -F: ‘$NF=="/bin/bash" {print $1,$NF}‘ /etc/passwd

[root@centos8 ~]# awk -F: ‘$NF=="/bin/bash"{print $1,$NF}‘ /etc/passwd
root /bin/bash
wang /bin/bash
long /bin/bash

[root@centos8 ~]# awk -F: ‘$NF ~ /bash$/{print $1,$NF}‘ /etc/passwd

root /bin/bash
wang /bin/bash
long /bin/bash

line ranges:行范围
不支持直接用行号,但可以使用变量NR间接指定行号
/pat1/,/pat2/ 不支持直接给出数字格式
范例:

[root@centos8 ~]# seq 10 | awk ‘NR>=3 && NR<=6‘
3
4
5
6
[root@centos8 ~]# awk ‘NR>=3 && NR<=6{print NR,$0}‘ /etc/passwd
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync

[root@centos8 ~]# sed -n ‘3,6p‘ /etc/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync

[root@centos8 ~]# awk ‘/^bin/,/^adm/‘ /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin

[root@centos8 ~]# sed -n ‘/^bin/,/^adm/p‘ /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin

BEGIN/END模式
BEGIN{}:仅在开始处理文件中的文本之前执行一次

END{}:仅在文本处理完成之后执行一次
范例

awk -F: ‘BEGIN {print "USER USERID"} {print $1":"$3} END{print "END FILE"}‘ /etc/passwd

awk -F: ‘{print "USER USERID";print  $1":"$3}END{print  "END FILE"}‘  /etc/passwd

awk -F: ‘BEGIN{print "USER UID  ------------------"}{print  $1,$3}‘ /etc/passwd

awk -F: ‘BEGIN{print "USER UID  ------------------"}{print  $1,$3}END{print"=============="}‘ /etc/passwd

范例

seq 10 | awk ‘i=0‘

seq 10 | awk ‘i=1‘

seq 10 | awk ‘i=!i‘

seq 10 | awk ‘{i=!i;print i}‘

seq 10 | awk ‘!(i=!i)‘

seq 10 | awk -v i=1 ‘i=!i‘

[root@centos8 ~]# seq 10 | awk ‘i=0‘

[root@centos8 ~]# seq 10 | awk ‘i=1‘
1
2
3
4
5
6
7
8
9
10
[root@centos8 ~]# seq 10 | awk ‘i=1‘

1
2
3
4
5
6
7
8
9
10
[root@centos8 ~]# seq 10 | awk ‘i=0‘

[root@centos8 ~]# seq 10 | awk ‘i=!i‘
1
3
5
7
9
[root@centos8 ~]# seq 10 | awk ‘!(i=!i)‘
2
4
6
8
10
[root@centos8 ~]# seq 10 | awk -v i=1 ‘i=!i‘

2
4
6
8
10
[root@centos8 ~]# seq 10 | awk -v i=0 ‘i=!i‘
1
3
5
7
9
[root@centos8 ~]# seq 10 | awk ‘{i=!i;print i}‘

1
0
1
0
1
0
1
0
1
0

条件判断 if-else

语法:

if(condition){statement;…}[else statement]

if(condition1){statement1}else if(condition2){statement2}else if(condition3)

{statement3}......else{statementN}

使用场景:对awk取得的整行或某个字段做条件判断
范例:

awk -F: ‘{if($3>=1000)print $1,$3}‘ /etc/passwd

awk -F: ‘{if($NF=="/bin/bash") print $1}‘ /etc/passwd

awk ‘{if(NF>5) print $0}‘ /etc/passwd

awk -F: ‘{if($3>=1000) {printf "Common user: %s ",$1} else {printf "root or Sysuser: %s ",$1}}‘ /etc/passwd

awk -F:  ‘{if($3>=1000) printf "Common user: %s ",$1; else printf "root or Sysuser: %s ",$1}‘ /etc/passwd

df -h | awk -F% ‘/^/dev/sd/{print $1}‘ | awk ‘$NF>=80{print $1,$5}‘

df | awk -F"[[:space:]]+|%" ‘/^/dev/sd/{if($5>80) print $1,$5}‘

[root@centos8 ~]# df | awk -F‘ +|%‘ ‘/^/dev/sd/{if($5>=10)print $1,$5}‘
/dev/sda1 15

awk ‘BEGIN{ test=100;if(test>90) {print "very good"} else if(test>60) {print "good"} else {print "no pass"}}‘

switch 语句

语法:

switch(expression) {case VALUE1 or /REGEXP/: statement1; case VALUE2 or
/REGEXP2/: statement2; ...; default: statementn}

循环 while

语法:

while (condition) {statement;…}

条件“真”,进入循环;条件“假”,退出循环
使用场景:
  对一行内的多个字段逐一类似处理时使用

  对数组中的各元素逐一处理时使用

示例

#内置函数length()返回字符数,而非字节数
[root@centos8 ~]# awk ‘BEGIN{print length("hello")}‘
5
[root@centos8 ~]# awk ‘BEGIN{print length("九五至尊")}‘
4
[root@centos7 ~]# awk ‘/^[[:space:]]*linux16/{i=1;while(i<=NF){print $i,length($i); i++}}‘ /etc/grub2.cfg
linux16 7
/vmlinuz-3.10.0-1062.el7.x86_64 31
root=UUID=bebb9244-bbb8-4c69-9249-54a36c75155e 46
ro 2
crashkernel=auto 16
rhgb 4
quiet 5
net.ifnames=0 13
linux16 7
/vmlinuz-0-rescue-b12558570741487c9328c996e3265b09 50
root=UUID=bebb9244-bbb8-4c69-9249-54a36c75155e 46
ro 2
crashkernel=auto 16
rhgb 4
quiet 5
net.ifnames=0 13

[root@centos7 ~]# awk ‘/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=10){print $i,length($i)}; i++}}‘ /etc/grub2.cfg
/vmlinuz-3.10.0-1062.el7.x86_64 31
root=UUID=bebb9244-bbb8-4c69-9249-54a36c75155e 46
crashkernel=auto 16
net.ifnames=0 13
/vmlinuz-0-rescue-b12558570741487c9328c996e3265b09 50
root=UUID=bebb9244-bbb8-4c69-9249-54a36c75155e 46
crashkernel=auto 16
net.ifnames=0 13

[root@centos8 ~]# awk ‘BEGIN{ total=0;i=1; while(i<=100) { total+=i;i++}; print total}‘

5050

循环 do-while

语法:

do {statement;…}while(condition)

意义:无论真假,至少执行一次循环体

do-while循环
语法:do {statement;…}while(condition)

意义:无论真假,至少执行一次循环体
范例:

[root@centos8 ~]# awk ‘BEGIN{ total=0;i=1;do{ total+=i;i++;} while(i<=100);print total}‘

5050

循环 for

语法:

for(expr1;expr2;expr3) {statement;…}

常见用法

for(variable assignment;condition;iteration process) {for-body}

特殊用法:能够遍历数组中的元素

for(var in array) {for-body}

范例:

[root@centos8 ~]# awk ‘BEGIN{ total=0;for(i=1;i<=100;i++){ total+=i};print total}‘

5050

[root@centos8 ~]# awk ‘/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}‘ /etc/grub2.cfg

linux16 7
/vmlinuz-3.10.0-1062.el7.x86_64 31
root=UUID=bebb9244-bbb8-4c69-9249-54a36c75155e 46
ro 2
crashkernel=auto 16
rhgb 4
quiet 5
net.ifnames=0 13
linux16 7
/vmlinuz-0-rescue-b12558570741487c9328c996e3265b09 50
root=UUID=bebb9244-bbb8-4c69-9249-54a36c75155e 46
ro 2
crashkernel=auto 16
rhgb 4
quiet 5
net.ifnames=0 13

性能比较

time (awk ‘BEGIN{ total=0;for(i=0;i<=10000;i++){total+=i;};print total;}‘)

time (total=0;for i in {1..10000};do total=$(($total+i));done;echo $total)

time (for ((i=0;i<=10000;i++));do let total+=i;done;echo $total)

time (seq –s ”+” 10000|bc)

continue 和 break

continue 中断本次循环

break 中断整个循环
格式:

continue [n]

break [n]

范例:

[root@centos8 ~]# awk ‘BEGIN{ sum=0;for(i=1;i<=100;i++) {if(i%2==0)continue; sum+=i}print sum}‘

2500

[root@centos8 ~]# awk ‘BEGIN{ sum=0;for(i=1;i<=100;i++){if(i==50)break; sum+=i}print sum}‘

1225

next

next 可以提前结束对本行处理而直接进入下一行处理(awk自身循环)
范例:

[root@centos8 ~]# awk -F: ‘{if($3%2!=0) next; print $1,$3}‘ /etc/passwd
root 0
daemon 2
lp 4
shutdown 6
mail 8
games 12
ftp 14
nobody 65534
polkitd 998
gluster 996
rtkit 172
rpc 32
chrony 994
saslauth 992
clevis 984
pegasus 66
colord 982
setroubleshoot 980
gdm 42
gnome-initial-setup 978
sshd 74
avahi 70
tcpdump 72
long 1000

数组

awk的数组为关联数组

格式

array_name[index-expression]

范例:

weekdays["mon"]="Monday"

index-expression
  利用数组,实现 k/v 功能

  可使用任意字符串;字符串要使用双引号括起来

  如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为“空串”

  若要判断数组中是否存在某元素,要使用“index in array”格式进行遍历
范例:

[root@centos8 ~]# awk ‘BEGIN{ weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";print weekdays["mon"]}‘

Monday

范例:

awk ‘!line[$0]++‘  dupfile

awk ‘{!line[$0]++;print $0, line[$0]}‘ dupfile

范例:判断数组索引是否存在

[root@centos8 ~]# awk ‘BEGIN{ array["i"]="x"; array["j"]="y" ; print "i" in array, "y" in array }‘

1  0

[root@centos8 ~]# awk ‘BEGIN{ array["i"]="x"; array["j"]="y" ; if ("i" in array) {print "存在"}else{print "不存在"}}‘

存在

[root@centos8 ~]# awk ‘BEGIN{ array["i"]="x";array["j"]="y" ; if ("abc" in array) {print "存在"}else{print "不存在"}}‘

不存在

若要遍历数组中的每个元素,要使用for循环

for(var in array) {for-body}

注意:var会遍历array的每个索引

范例:遍历数组

[root@centos8 ~]# awk ‘BEGIN{ weekdays["mon"]="Monday" ; weekday["tue"]="Tuesday" ; for(i in weekdays) {print weekdays[i]}}‘

Tuesday
Monday

[root@centos8 ~]# awk ‘BEGIN{ students[1]="yuzong"; students[2]="longzong"; students[3]="xuzong"; for(x in students) {print x ":"students[x]}}‘

1:yuzong

2:longzong

3:xuzong

[root@centos8 ~]# awk ‘BEGIN{

a["x"] = "welcome"

a["y"] = "to"

a["z"] = "longzu"

for (i in a) {

  print i,a[i]

}

}‘

x welcome

y to

z longzu

[root@centos8 ~]# awk -F: ‘{ user[$1]=$3}END{ for(i in user){print "username:" i,"uid:" user[i]}}‘ /etc/passwd

username: adm uid: 3
username: rpc uid: 32
username: dnsmasq uid: 985
username: radvd uid: 75
username: sync uid: 5
username: mail uid: 8

范例:显示主机的连接状态出现的次数

[root@centos8 ~]# awk ‘NR!=1{print $1}‘ sos.log | sort | uniq -c

18 ESTAB

1 FIN-WAIT-1

10 LAST-ACk

[root@centos8 ~]# cat sos.log | sed -nr ‘1!s/^([0-9]+) .*/1/p‘ | sort | uniq -c

233 ESTAB

8 LISTEN

128 SYN-RECV

98 TIME-WAIT

[root@centos8 ~]# ss -ant | awk ‘NR!=1 {state[$1]++}END{ for (i in state){print i,state[i]}}‘

SYN-RECV 128

LISTEN  8

ESTAB  233

TIME-WAIT  98

[root@centos8 ~]# netstat -tan | awk ‘/^tcp/{state[$NF]++}END{ for (i in state){print i,state[i]}}‘

LISTEN 8

SYN-RECV  128

ESTABLISHED  280

FIN-WAIT2  50

范例

[root@centos8 ~]# awk ‘{ip[$1]++}END{ for(i in ip){print i,ip[i]}}‘ /var/log/httpd/access.log

172.20.0.200 1482
172.20.21.121 2
172.20.30.91 29
172.16.102.29 864
172.20.0.76 1565
172.20.9.9 15
172.20.73.73 198

[root@centos8 ~]# awk ‘{ip[$1]++}END{ for (i in ip){print ip[i],i}}‘ access.log | sort -nr | head -n3

4870 172.20.116.228
3429 172.20.116.208
2834 172.20.0.222

[root@centos8 ~]# awk ‘{ip[$1]++}END{ for (i in ip){print i,ip[i]}}‘ access.log | sort -k2 -nr | head -n3

172.20.116.228 4870
172.20.116.208 3429
172.20.0.222 2834

范例:封掉查看访问日志中连接次数超过1000次的IP

[root@centos8 ~]# awk ‘{ip[$1]++}END{ for(i in ip){if(ip[i]>=1000){sytem("iptables -A INPUT -s "i" -j  REJECT")}}}‘  nginx.access.log-20200714

范例:多维数组

[root@centos8 ~]# awk ‘BEGIN{

array[1][1]=11

array[1][2]=12

array[1][3]=13

array[2][1]=21

array[2][2]=22

for (i in array)

  for(j in array[i])

    print array[i][j]

}‘

11

12

13

21

22

 

  awk函数

awk 的函数分为内置和自定义函数

  常见内置函数

数值处理:
rand():返回0和1之间一个随机数

srand():配合rand() 函数,生成随机数的种子

int():返回整数

范例:

[root@centos8 ~]# awk ‘BEGIN{srand();print rand()}‘
0.790437
[root@centos8 ~]# awk ‘BEGIN{srand();print rand()}‘
0.283736
[root@centos8 ~]# awk ‘BEGIN{srand();print rand()}‘
0.948082
[root@centos8 ~]# awk ‘BEGIN{srand();print rand()}‘
0.371798

[root@centos8 ~]# awk ‘BEGIN{srand(); for (i =1;i<=10;i++)print int(rand()*100)}‘

35
17
35
95
19
15
70
54
46
93

字符串处理:
length([s]):返回指定字符串的长度

sub(r,s,[t]):对t字符串搜索r表示模式匹配的内容,并将第一个匹配内容替换为s

范例:

[root@centos8 ~]# echo "2008:08:08 08:08:08" | awk ‘sub(/:/,"-",$1)‘
2008-08:08 08:08:08

[root@centos8 ~]# echo "2008:08:08 08:08:08" | awk ‘{sub(/:/,"-",$1);print $0}‘
2008-08:08 08:08:08

gsub(r,s,[t]):对t字符串进行搜索r表示的模式匹配的内容,并全部替换为s所表示的内容
范例:

[root@centos8 ~]# echo "2008:08:08 08:08:08" | awk ‘gsub(/:/,"-",$0)‘
2008-08-08 08-08-08

[root@centos8 ~]# echo "2008:08:08 08:08:08" | awk ‘{gsub(/:/,"-",$0);print $0}‘
2008-08-08 08-08-08

split(s,array,[r]):以r为分隔符,切割字符串s,并将切割后的结果保存至array所表示的数组中,第一个索引值为1,第二个索引值为2,…

范例:

[root@centos8 ~]# netsta -tn | awk ‘/^tcp/{split($5,ip,":");count[ip[1]]++}END{ for (i in count){print i,count[i]}}‘

10.0.0.1 1
10.0.0.6 1
10.0.0.7 673

system 函数:可以awk中调用shell命令

空格是awk中的字符串连接符,如果system中需要使用awk中的变量可以使用空格分隔,或者说除了awk的变量外其他一律用""引用起来

awk ‘BEGIN{ system("hostname")}‘

awk ‘BEGIN{score=100; system("echo your score is" score)}‘

[root@centos8 ~]# netsta -tn | awk ‘/^tcp/{split($5,ip,":");count[ip[1]]++}END{ for (i in count){ if(count[i]>=10){ system("iptables -A INPUT -s "i" -j REJECT")}}}‘

  自定义函数

自定义函数格式:

function name ( parameter, parameter, ... ) {
statements
return expression
}

范例:

[root@centos8 ~]# cat func.awk

function max(x,y){

  x>y?var=x:var=y

  return var

}

BEGIN{print max(a,b)}

[root@centos8 ~]# awk -v a=30 -v b=20 -f func.awk

30

  awk脚本

将awk程序写成脚本,直接调用或执行
范例:

[root@centos8 ~]# cat passwd.awk

{ if($3>=1000)print $1,$3}

[root@centos8 ~]# awk -F: -f passwd.awk  /etc/passwd

nobody 65534
wang 1000
long 1001

范例:

[root@centos8 ~]# cat test.awk

#!/bin/awk -f

# this is a awk script

{ if($3>=1000)print $1,$3}

[root@centos8 ~]# chmod +x test.awk

[root@centos8 ~]# ./test.awk -F:  /etc/passwd

nobody 65534
wang 1000
long 1001

向awk脚本传递参数
格式:

awkfile var=value var2=value2... Inputfile

注意:在BEGIN过程中不可用。直到首行输入完成以后,变量才可用。可以通过-v 参数,让awk在执行BEGIN之前得到变量的值。命令行中每一个指定的变量都需要一个-v参数

范例:

[root@centos8 ~]# cat test2.awk

#!/bin/awk -f

{ if($3>=min && $3<=max) print $1,$3}

[root@centos8 ~]# chmod +x test2.awk

[root@centos8 ~]#./test2.awk -F:  min=100 max=200 /etc/passwd

systemd-resolve 193
rtkit 172
pulse 171
qemu 107
usbmuxd 113
abrt 173

以上是关于随堂练习 文本处理三剑客 AWK的主要内容,如果未能解决你的问题,请参考以下文章

Shell文本处理工具(Linux三剑客 grep sed awk )

Linux文本三剑客之一——awk详解——awk看这两篇就够啦~PS:文末有练习,来练练手吧

文本处理三剑客之gawk

文本处理三剑客之awk

文本处理三剑客之AWK

文本处理三剑客之awk(原创)