awk 工作原理和基本用法说明
常见选项:
-F “分隔符” 指明输入时用到的字段分隔符
-v var=value 变量赋值
动作:printf
说明:
逗号分隔符
输出item可以字符串,也可是数值;当前记录的字段、变量或awk的表达式
如省略item,相当于print $0
范例:
[root@I|158|~]#awk -F: '{print $1,$3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
operator 11
games 12
ftp 14g
nobody 99
[root@I|160|~]#awk -F: '{print $1"\t"$3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
operator 11
games 12
ftp 14
[root@I|162|~]#grep "^UUID" /etc/fstab
UUID=7e896ac6-4ee4-4533-ad7e-578c71560735 / xfs defaults 0 0
UUID=a063884c-6421-4581-841b-a13cdc73c254 /boot xfs defaults 0 0
UUID=da6657db-cf66-4ef8-b39f-ff6cf39414f6 /data xfs defaults 0 0
UUID=09bcc722-93e2-497c-a51b-480bc92fafc5 swap swap defaults 0 0
UUID=ed7ec688-ffc1-401f-9af9-ab6224d0aab1 /mnt ext4 defaults 0 0
UUID=17a95356-e38c-434a-94fc-99819021cc87 swap swap defaults 0 0
[root@I|161|~]#grep "^UUID" /etc/fstab | awk {'print $2,$3'}
/ xfs
/boot xfs
/data xfs
swap swap
/mnt ext4
swap swap
[root@I|166|~]#df | awk -F"[[:space:]]+|%" '{print $5}'
已用
0
0
2
0
7
1
1
18
1
1
100
[root@I|168|~]#df | awk -F"[[:space:]]+|%" '/^\/dev\/sd{print $5}'
7
1
1
18
awk变量
awk中的变量分为:内置和自定义变量
常见的内置变量
FS:输入字段分隔符,默认为空白字符,功能相当于 -F
范例:
awk -v FS=":" '{print $1FS$3}' /etc/passwd
awk –F: '{print $1,$3,$7}' /etc/passwd
S=:;awk -v FS=$S '{print $1FS$3}' /etc/passwd
OFS:输出字段分隔符,默认为空白字符
[root@centos8|2|~]#awk -v FS=':' -v OFS=':' '{print $1,$3,$7}' /etc/passwd
root:0:/bin/bash
bin:1:/sbin/nologin
daemon:2:/sbin/nologin
adm:3:/sbin/nologin
lp:4:/sbin/nologin
sync:5:/bin/sync
shutdown:6:/sbin/shutdown
RS:输入记录分隔符,指定输入时的换行符
[root@centos8|8|~]#awk -v RS=' ' '{print $0}' /etc/passwd
ORS:输出记录分隔符,输出时用指定符号代替换行符
[root@centos8|12|~]#awk -v RS=' ' -v ORS='###' '{print $0}' /etc/passwd
NF:字段数量
范例:
[root@centos8 ~]#awk -F:'{print NF}' /etc/fstab
[root@centos8|19|~]#awk -F: '{print $(NF-1)}' /etc/passwd
[root@centos7|28|expect.txt]#ls /misc/cd/Packages/*.rpm |awk -F"." '{print $(NF-1)}'|sort|uniq -c
2281 i686
3155 noarch
4661 x86_64
[root@centos7|37|~]#ss -nt | awk -F"[[:space:]]+|:" '/^ESTAB/{print $(NF-2)}'
范例: 将连接数超过3个以上的IP放入黑名单拒绝访问
[root@centos8|57|script]#cat 5.sh
#!/bin/bash
while :;do
ss -nt | awk -F"[[:space:]]+|:" '/^ESTAB/{print $(NF-2)}'|sort|uniq -c|while read count ip;do
if [ $count -gt 3 ];then
iptables -A INPUT -s $ip -j REJECT
fi
done
sleep 10
done
NR:记录编号
范例:
[root@centos8 ~]#awk -F: '{print NR}' /etc/passwd
123
.......
[root@centos8 ~]#awk -F: 'END{print NR}' /etc/passwd
57
[root@centos8 ~]#awk -F: 'BEGIN{print NR}' /etc/passwd
FNR:各文件分别计数,记录号
范例:
awk '{print FNR}' /etc/fstab /etc/inittab
[root@centos8 ~]#awk '{print NR,$0}' /etc/issue /etc/redhat-release
1 \S
2 Kernel \r on an \m
34 CentOS Linux release 8.0.1905 (Core)
[root@centos8 script40]#awk '{print FNR,$0}' /etc/issue /etc/redhat-release
1 \S
2 Kernel \r on an \m
31 CentOS Linux release 8.0.1905 (Core)
FILENAME:当前文件名
范例:
[root@centos8 ~]#awk '{print FILENAME}' /etc/fstab
[root@centos8 ~]#awk '{print FNR,FILENAME,$0}' /etc/issue /etc/redhat-release
1 /etc/issue \S
2 /etc/issue Kernel \r on an \m
3 /etc/issue
1 /etc/redhat-release CentOS Linux release 8.0.1905 (Core)
ARGC:命令行参数的个数
范例
[root@centos8 ~]#awk '{print ARGC}' /etc/issue /etc/redhat-release
3333
[root@centos8 ~]#awk 'BEGIN{print ARGC}' /etc/issue /etc/redhat-release
3
ARGV:数组,保存的是命令行所给定的各参数
范例:
[root@centos8 ~]#awk 'BEGIN{print ARGV[0]}' /etc/issue /etc/redhat-release
awk
[root@centos8 ~]#awk 'BEGIN{print ARGV[1]}' /etc/issue /etc/redhat-release
/etc/issue
[root@centos8 ~]#awk 'BEGIN{print ARGV[2]}' /etc/issue /etc/redhat-release
/etc/redhat-release
[root@centos8 ~]#awk 'BEGIN{print ARGV[3]}' /etc/issue /etc/redhat-release
[root@centos8 ~]#
自定义变量(区分字符大小写)
-v var=value
在program中直接定义
awk -v test='hello gawk' '{print test}' /etc/fstab
awk -v test='hello gawk' 'BEGIN{print test}'
awk 'BEGIN{test="hello,gawk";print test}'
awk -F: '{sex="male";print $1,sex,age;age=18}' /etc/passwd
cat awkscript
{print script,$1,$2}
awk -F: -f awkscript script="awk" /etc/passwd
动作printf
printf 可以实现格式化输出
必须指定FORMAT
不会自动换行,需要显式给出换行控制符,\n
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\n",$1}' /etc/passwd
awk -F: '{printf "%-20s %10d\n",$1,$3}' /etc/passwd
awk -F: '{printf "Username: %s\n",$1}' /etc/passwd
awk -F: '{printf “Username: %sUID:%d\n",$1,$3}' /etc/passwd
awk -F: '{printf "Username: %25sUID:%d\n",$1,$3}' /etc/passwd
awk -F: '{printf "Username: %-25sUID:%d\n",$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}'
1 1
[root@centos8 ~]#awk 'BEGIN{i=0;print i++,i}'
0 1
比较操作符:
==, !=, >, >=, <, <=
模式匹配符:
~ 左边是否和右边匹配,包含关系
!~ 是否不匹配
[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}'
51
92
[root@centos8 ~]#ifconfig eth0 | awk 'NR==2{print $2}'
10.0.0.8
逻辑操作符:
与&&,或||,非!
范例:
awk -F: '$3>=0 && $3<=1000 {print $1}' /etc/passwd
awk -F: '$3==0 || $3>=1000 {print $1}' /etc/passwd
awk -F: '!($3==0) {print $1}' /etc/passwd
awk -F: '!($3>=500) {print $3}' /etc/passwd
条件表达式:
范例:
awk -F: '{$3>=1000?usertype="Common User":usertype="SysUser";printf "%-20s:%12s\n",$1,usertype}' /etc/passwd
模式匹配PATTERN
PATTERN:根据pattern条件,过滤匹配的行,再做处理
- 如果未指定:空模式,匹配每一行
范例:
[root@centos8 ~]#awk -F: '{print $1,$3}' /etc/passwd
- /regular expression/:仅处理能够模式匹配到的行,需要用/ /括起来
[root@centos7|125|~]#awk '/^UUID/{print $1}' /etc/fstab
UUID=7e896ac6-4ee4-4533-ad7e-578c71560735
UUID=a063884c-6421-4581-841b-a13cdc73c254
UUID=da6657db-cf66-4ef8-b39f-ff6cf39414f6
UUID=09bcc722-93e2-497c-a51b-480bc92fafc5
UUID=ed7ec688-ffc1-401f-9af9-ab6224d0aab1
UUID=17a95356-e38c-434a-94fc-99819021cc87
[root@centos7|126|~]#awk '!/^UUID/{print $1}' /etc/fstab
#
#
#
#
#
#
#
[root@centos7|127|~]#df | awk '/\/dev\/sd/'
/dev/sda2 104806400 6547656 98258744 7% /
/dev/sda3 52403200 33272 52369928 1% /data
/dev/sdb1 999320 2572 927936 1% /mnt
/dev/sda1 1038336 182952 855384 18% /boot
[root@centos7|128|~]#
- relational expression: 关系表达式,结果为“真”才会被处理
真:结果为非0值,非空字符串
假:结果为空字符串或0值
范例:
awk -F: 'i=1;j=1{print i,j}' /etc/passwd
awk '!0' /etc/passwd ;awk '!1' /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
awk -F: '$NF ~ /bash$/{print $1,$NF}' /etc/passwd
- line ranges:行范围
/pat1/,/pat2/ 不支持直接给出数字格式
[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
[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/syncs
5. 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
6. 条件判断if else
语法:
if(condition){statement;…}[else statement]
if(condition1){statement1}else if(condition2){statement2}else{statement3}
范例:
[root@centos7|100|~]#awk -F: '{if($3>=1000)print $1,$3}' /etc/passwd
nfsnobody 65534
yao 1002
linyao 1000
lin 1003
tomcat 1004
test 1005
roob 1006
gordon 1007
mage 1008
wang 1009
liu 1011
lll 1012
xiaohong 1013
xiaobai 1014
baid 1015
asd 1016
tom 1017
cat 1018
[root@centos7|101|~]#awk -F: '{if($NF=="/bin/bash")print $1}' /etc/passwd
root
yao
lin
tomcat
test
roob
mage
wang
liu
lll
xiaohong
xiaobai
baid
asd
tom
cat
[root@centos7|102|~]#awk '{if(NF>5)print $0}' /etc/fstab
# Created by anaconda on Sun Dec 8 16:12:05 2019
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
UUID=7e896ac6-4ee4-4533-ad7e-578c71560735 / xfs defaults 0 0
UUID=a063884c-6421-4581-841b-a13cdc73c254 /boot xfs defaults 0 0
UUID=da6657db-cf66-4ef8-b39f-ff6cf39414f6 /data xfs defaults 0 0
UUID=09bcc722-93e2-497c-a51b-480bc92fafc5 swap swap defaults 0 0
UUID=ed7ec688-ffc1-401f-9af9-ab6224d0aab1 /mnt ext4 defaults 0 0
UUID=17a95356-e38c-434a-94fc-99819021cc87 swap swap defaults 0 0
[root@centos7|107|~]#awk -F: '{if($3>=1000){printf "Common user: %s\n",$1}else {printf "root or systemuser : %s\n",$1}}' /etc/passwd
root or systemuser : root
root or systemuser : bin
root or systemuser : daemon
root or systemuser : adm
root or systemuser : lp
root or systemuser : sync
root or systemuser : shutdown
root or systemuser : halt
root or systemuser : mail
root or systemuser : operator
root or systemuser : games
root or systemuser : ftp
root or systemuser : nobody
root or systemuser : systemd-network
root or systemuser : dbus
root or systemuser : polkitd
root or systemuser : sssd
root or systemuser : libstoragemgmt
[root@centos7|113|~]#awk -F: '{if($3>=1000) printf "Common user: %s\n",$1; else printf "root or systemuser : %s\n",$1}' /etc/passwd
[root@centos7|133|~]#df -h|awk -F% '/^\/dev\/sd/{print $1}'| awk '$NF>=10{print $1,$5}'
/dev/sda1 18
[root@centos7|138|~]#df | awk -F"[[:space:]]+|%" '/^\/dev\/sd/{if($5>5)print $1,$5}'
/dev/sda2 7
/dev/sda1 18
[root@centos7|148|~]#awk 'BEGIN{ test=100;if(test>90){print "very good"} else if(test>60){print "good"}else{print "no pass"}}'
very good
switch语句
语法:
switch(expression) {case VALUE1 or /REGEXP/: statement1; case VALUE2 or
/REGEXP2/: statement2; ...; default: statementn}
循环while
while (condition) {statement;…}
条件“真”,进入循环;条件“假”,退出循环
使用场景:
对一行内的多个字段逐一类似处理时使用
对数组中的各元素逐一处理时使用
[root@centos7|153|~]#awk 'BEGIN{print length("hello")}'
5
[root@centos7|167|~]#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=7e896ac6-4ee4-4533-ad7e-578c71560735 46
ro 2
crashkernel=auto 16
spectre_v2=retpoline 20
rhgb 4
quiet 5
net.ifnames=0 13
linux16 7
/vmlinuz-0-rescue-d85d4d1db0304637b8f76d3d5d3dc54c 50
root=UUID=7e896ac6-4ee4-4533-ad7e-578c71560735 46
ro 2
crashkernel=auto 16
spectre_v2=retpoline 20
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@centos7|178|~]#awk 'BEGIN{total=0;i=1;while(i<=100){total+=i;i++}print total}'
5050
循环 do-while
[root@centos7|1|~]#awk 'BEGIN{total=0;i=1;do{total+=i;i++}while(i<=100);print total}'
5050
for循环
语法:
for(expr1;expr2;expr3) {statement;…}
特殊语法:能够遍历数组中的元素
for(var in array) {for-body}
范例:
[root@centos7|4|~]#awk 'BEGIN{total=0;for(i=1;i<=100;i++){total+=i};print total}'
5050
范例:
[root@centos7|27|~]#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=7e896ac6-4ee4-4533-ad7e-578c71560735 46
ro 2
crashkernel=auto 16
spectre_v2=retpoline 20
rhgb 4
quiet 5
net.ifnames=0 13
linux16 7
/vmlinuz-0-rescue-d85d4d1db0304637b8f76d3d5d3dc54c 50
root=UUID=7e896ac6-4ee4-4533-ad7e-578c71560735 46
ro 2
crashkernel=auto 16
spectre_v2=retpoline 20
rhgb 4
quiet 5
net.ifnames=0 13
continue和break
范例:
[root@centos7|44|~]#awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2==0)continue;sum+=i} print sum }'
2500
[root@centos7|46|~]#awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i==50)break;sum+=i} print sum }'
1225
next
next 可以提前结束对本行处理而直接进入下一行处理(awk自身循环)
[root@centos7|47|~]#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
systemd-network 192
sssd 998
colord 996
rpc 32
saslauth 994
rtkit 172
chrony 992
数组
awk的数组为关联数组
可使用任意字符串;字符串要使用双引号括起来
如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为“空串”
若要判断数组中是否存在某元素,要使用“index in array”格式进行遍历
[root@centos7|48|~]#awk 'BEGIN{weekdays["mon"]="Monday";weekdays["true"];print weekdays["mon"]}'
Monday
范例:
awk '!line[$0]++' dupfile
awk '{!line[$0]++;print $0, line[$0]}' dupfile
判断数组索引是否存在:
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}
[root@centos7|54|~]#awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";weekdays["wed"]="WENdays";for(i in weekdays){print weekdays[i]}}'
WENdays
Tuesday
Monday
[root@centos7|81|~]#awk -F: '{user[$1]=$3}END{for(i in user){print i,user[i]}}' /etc/passwd
[root@centos7|90|~]#cat ss.log | sed -nr '1!s/^([^0-9]+) .*/\1/p'|sort |uniq -c
27 ESTAB
[root@centos7|99|~]#ss -ant | awk 'NR!=1{state[$1]++}END{for(i in state){print i,state[i]}}'
LISTEN 16
ESTAB 2
[root@centos8 ~]#netstat -tan | awk '/^tcp/{state[$NF]++}END{for(i in state)
{print i,state[i]}}'
LISTEN 9
SYN_RECV 126
ESTABLISHED 523
FIN_WAIT2 40
[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.1.125 463
172.20.61.11 2
172.20.73.73 198
[root@centos8 ~]#awk '{ip[$1]++}END{for(i in ip){print i,ip[i]}}' access_log
|sort -k2 -nr|head -3 #k指定第二列来排序
172.20.116.228 4870
172.20.116.208 3429
172.20.0.222 2834
多维数组
[root@centos8 ~]#awk 'BEGIN{
> array[1][1]=11
> array[1][2]=12
> array[1][3]=13
> array[2][1]=21
> array[2][2]=22
> array[2][3]=23
> for (i in array)
> for (j in array[i])
> print array[i][j]
> }'
11
12
13
21
22
23
awk函数
awk 的函数分为内置和自定义函数
常见内置函数
数值处理:
rand():返回0和1之间一个随机数
srand():配合rand() 函数,生成随机数的种子
int():返回整数
[root@centos7|105|~]#awk 'BEGIN{srand();print rand()}'
0.32151
[root@centos7|106|~]#awk 'BEGIN{srand();for(i=1;i<=10;i++)print int (rand()*100)}'
49
47
82
59
25
5
82
46
0
54
字符串处理:
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 ~]#netstat -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 'BEGIN{system("hostname")}'
awk 'BEGIN{score=100; system("echo your score is " score) }'
[root@centos8 ~]#netstat -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")}}}'
自定义函数
[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脚本
[root@centos8 ~]#cat passwd.awk
{if($3>=1000)print $1,$3}
[root@centos8 ~]#awk -F: -f passwd.awk /etc/passwd
nobody 65534
wang 1000
范例:
去重:
[root@centos7|179|~]# tail /etc/services | awk '{a[$1]++}END{for (v in a)print v}'
isnetserv 48128/udp # Image Systems Network Services
blp5 48129/udp # Bloomberg locator
com-bardac-dw 48556/udp # com-bardac-dw
iqobject 48619/udp # iqobject
[root@centos7|184|~]#tail /etc/services |awk '{print a[$1]++?$1:"no"}'
no
no
isnetserv
no
blp5
no
com-bardac-dw
no
iqobject
no
[root@centos7|187|~]#tail /etc/services | awk -F '[ /]+' '{a[$1]+=$2}END{for(v in a)print v,a[v]}'
com-bardac-dw 97112
3gpp-cbsp 48049
iqobject 97238
matahari 49000
isnetserv 96256
blp5 96258
[root@centos7|6|~]#tail /etc/services | awk '{a[$1]++}END{for (v in a)print a[v],v}'
2 com-bardac-dw
1 3gpp-cbsp
2 iqobject
1 matahari
2 isnetserv
2 blp5
内置函数
int()
[root@centos7|10|~]#echo "123abc abc123 123abc123"|xargs -n1 | awk '{print int($0)}'
123
0
123
[root@centos7|11|~]#awk 'BEGIN{print int(10/3)}'
3
rand()
[root@centos7|12|~]#awk 'BEGIN{srand();print rand()}'
0.719291
[root@centos7|13|~]#awk 'BEGIN{srand();print rand()}'
0.719291
[root@centos7|14|~]#awk 'BEGIN{srand();print rand()}'
0.166282
[root@centos7|22|~]#awk 'BEGIN{srand();print int (rand()*10)}'
2
[root@centos7|23|~]#awk 'BEGIN{srand();print int (rand()*10)}'
2
[root@centos7|24|~]#awk 'BEGIN{srand();print int (rand()*10)}'
5
[root@centos7|25|~]#awk 'BEGIN{srand();print int (rand()*10)}'
5
[root@centos7|26|~]#awk 'BEGIN{srand();print int (rand()*10)}'
4
替换:在行前加东西
[root@centos7|30|~]#seq 5 | awk 'NR==2{sub('/.*/',"txt\n&")}{print}'
1
txt
2
3
4
5
[root@centos7|31|~]#seq 5 | awk 'NR==2{sub('/.*/',"&\ntxt")}{print}'
1
2
txt
3
4
5
awk IO语句
[root@centos7|40|~]#seq 5 | awk '/3/{getline;print}'
4 #获取下一条输入的语句
把匹配的下一行加*
[root@centos7|43|~]#seq 5 | awk '/3/{getline;sub(".*","&*");print}'
4*
[root@centos7|45|~]#awk 'BEGIN{while("seq 5"|getline)print}'
1
2
3
4
5
next 当遇到next后面的就不执行
[root@centos7|46|~]#seq 5 | awk '{if ($0==3){next}else{print}}'
1
2
4
5
[root@centos7|49|~]#seq 5 | awk 'NR==1{next}{print $0}'
2
3
4
5
[root@centos7|52|~]#seq 5 | awk 'NR!=1{print $0}'
2
3
4
5
对awk处理后的结果进行操作
[root@centos7|53|~]#tail -n5 /etc/services |awk '{print $2 |"sort"}'
48556/tcp
48556/udp
48619/tcp
48619/udp
49000/tcp
awk需求案例及常见面试题:
对比两个文件:找b文件在a文件相同记录
[root@centos7|73|~]#cat a
1
2
3
4
5
[root@centos7|74|~]#cat b
3
4
5
6
7
[root@centos7|75|~]#awk 'FNR==NR{a[$0];next}{if($0 in a)print $0}' a b
3
4
5
[root@centos7|77|~]#awk 'FNR==NR{a[$0];next}{if($0 in a)print FILENAME,$0}'
b 3
b 4
b 5
[root@centos7|78|~]#awk 'FNR==NR{a[$0]}NR>FNR{if($0 in a)print $0}' a b
3
4
5
[root@centos7|81|~]#awk 'FNR==NR{a[$0]=1;next}(a[$0]==1)' a b
3
4
5
不同的文件:
[root@centos7|83|~]#awk 'FNR==NR{a[$0]=1;next}!($0 in a)' a b
6
7
[root@centos7|49|~]#seq 5 | awk 'NR==1{next}{print $0}'
2
3
4
5
[root@centos7|52|~]#seq 5 | awk 'NR!=1{print $0}'
2
3
4
5
对awk处理后的结果进行操作
[root@centos7|53|~]#tail -n5 /etc/services |awk '{print $2 |"sort"}'
48556/tcp
48556/udp
48619/tcp
48619/udp
49000/tcp
awk需求案例及常见面试题:
对比两个文件:找b文件在a文件相同记录
[root@centos7|73|~]#cat a
1
2
3
4
5
[root@centos7|74|~]#cat b
3
4
5
6
7
[root@centos7|75|~]#awk 'FNR==NR{a[$0];next}{if($0 in a)print $0}' a b
3
4
5
[root@centos7|77|~]#awk 'FNR==NR{a[$0];next}{if($0 in a)print FILENAME,$0}'
b 3
b 4
b 5
[root@centos7|78|~]#awk 'FNR==NR{a[$0]}NR>FNR{if($0 in a)print $0}' a b
3
4
5
[root@centos7|81|~]#awk 'FNR==NR{a[$0]=1;next}(a[$0]==1)' a b
3
4
5
不同的文件:
[root@centos7|83|~]#awk 'FNR==NR{a[$0]=1;next}!($0 in a)' a b
6
7
来源:CSDN
作者:你是遥远的星河
链接:https://blog.csdn.net/qq_45414629/article/details/103946637