第一步:执记录BEGIN{action;...}语句块中的语句。
第二步:从文件或标准输入(stdin)读取一记录,然后执记录pattern{action;...}语句块,它逐记录扫描文件,从
第一记录到最后一记录重复这个过程,直到文件全部被读取完毕。
第三步:当读至输入流末尾时,执记录END{action;...}语句块。
BEGIN语句块在awk开始从输入流中读取记录之前被执记录,这是一个可选的语句块,比如变量初始化、打印输出表格
的表头等语句通常可写在BEGIN语句块中。
END语句块在awk从输入流中读完所有的记录之后被执记录,比如打印所有记录的分析结果这类信息汇总都是在END语句
块中完成,它也是一个可选语句块。
pattern语句块中的通用命令是最重要的部分,也是可选的。如果没有提供pattern语句块,则默认执记录
{print},即打印每一个读取到的记录,awk读取的每一记录都会执记录该语句块。
print格式:print item1, item2, ...
注意
逗号分隔符;
输出的各item可以是字符串,也可是数值;当前记录的字段、变量或awk的表达式;
如省略item,相当于print $0。
awk [options] 'program' var=value file ...
awk [options] -f programfile var=value file ...
awk [options] 'BEGIN{ action;...} pattern{ action;... } END{ action;... }' file ...
awk [options] 'program' file
program:表示为pattern{action statements;...}
pattern:表示部分决定动作语句何时触发及触发事件BEGIN、END;
action statements:表示对数据进记录处理,放置{}内指明print、printf。
awk执记录时,由分隔符的字段(域)标记$1,$2...$n称为域标识。$0为所有域,注意:和shell中变量$符含义不
同;
文件的每一记录称为记录;
省略action,则默认执记录print $0的操作。
awk省略action,默认执⾏print $0
[root@localhost data]# awk '{print}' awktest.txt
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
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
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
指定:(冒号)为分隔符,打印每⾏记录的第⼀个字段即输出$1
[root@localhost data]# awk -F: '{print $1}' awktest.txt
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
同理再把第三个字段输出,输出前添加三个连字符(—):
[root@localhost data]# awk -F: '{print $1"---"$3}' awktest.txt
root---0
bin---1
daemon---2
adm---3
lp---4
sync---5
shutdown---6
halt---7
mail---8
operator---11
取出磁盘使⽤率
[root@localhost data]# df | grep "/dev/sd" | awk '{print $5}'
5%
1%
17%
BEGIN的使⽤:
[root@localhost data]# awk '{print 2.5*3}' awktest.txt
7.5
7.5
7.5
7.5
7.5
7.5
7.5
7.5
7.5
7.5
[root@localhost data]# awk 'BEGIN{print 2.5*3}' awktest.txt
7.5
[root@localhost data]# awk 'BEGIN{print 2.5*3}'
7.5
FS:输入自动分隔符,默认为空白字符;
OFS:输出自动分隔符,默认为空白字符;
RS:输入记录分隔符,指定输入时的换记录符,原换记录符仍有效;
ORS:输出记录分隔符,输出时用指定符号代替换记录符;
NF:字段数量;
NR:记录号;
FNR:各文件分别计数,记录号;
FILENAME:当前文件名;
ARGC:命令记录参数的个数;
ARGV:数组,保存的是命令记录所给定的各参数。
以分号作为分隔符,取1,3;列
[root@localhost data]# awk -v FS=":" '{print $1,FS,$3}' awktest.txt
root : 0
bin : 1
daemon : 2
adm : 3
lp : 4
sync : 5
shutdown : 6
halt : 7
mail : 8
operator : 11
以分号作为分隔符,取1,3,7列 输出时以—作为分隔符
[root@localhost data]# awk -v FS=':' -v OFS='---' '{print $1,$3,$7}' awktest.txt
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
halt---7---/sbin/halt
mail---8---/sbin/nologin
operator---11---/sbin/nologin
读取文件第一记录,以:作为记录分隔符(通常一记录称为一条记录)
[root@localhost data]# head -1 awktest.txt | awk -v RS=':' '{print}'
root
x
0
0
root
/root
/bin/bash
输出时以—代替换记录符
[root@localhost data]# awk -v ORS='---' '{print}' awktest.txt
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---lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin---sync:x:5:0:sync:/sbin:/bin/sync---shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown---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---
以:作为分隔符,显示每记录有多少字段
[root@localhost data]# awk -F: '{print NF}' awktest.txt
7
7
7
7
7
7
7
7
7
7
以:作为分隔符,打印出每记录倒数第二的字段
[root@localhost data]# awk -F: '{print $(NF -1)}' awktest.txt
/root
/bin
/sbin
/var/adm
/var/spool/lpd
/sbin
/sbin
/sbin
/var/spool/mail
/root
打印文件记录号,且以:作为分隔符取第一个字段
[root@localhost data]# awk -F: '{print NR,$1}' awktest.txt
1 root
2 bin
3 daemon
4 adm
5 lp
6 sync
7 shutdown
8 halt
9 mail
10 operator
分别为每个各文件添加记录号即记录号
[root@localhost data]# awk '{print FNR,$1}' /etc/fstab /data/awktest.txt
1
2 #
3 #
4 #
5 #
6 #
7 #
8 #
9 UUID=cd2bff96-2cf9-4140-8d08-b1a26f2f5059
10 UUID=5f1115c9-0c0b-4e1c-a31d-35d4fd099b05
11 UUID=fd2a26b4-8caa-42cf-a78b-8372f7cae188
12 UUID=31b99478-3e9f-449a-96af-22213f566f8e
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
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
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 operator:x:11:0:operator:/root:/sbin/nologin
显示命令记录给定的参数个数
[root@localhost ~]# awk 'BEGIN{print ARGC}' /etc/fstab /etc/inittab
3
分别显示命令记录这个数组里的每个参数
[root@localhost ~]# awk 'BEGIN{print ARGV[0]}' /etc/fstab /etc/inittab
awk
[root@localhost ~]# awk 'BEGIN{print ARGV[1]}' /etc/fstab /etc/inittab
/etc/fstab
[root@localhost ~]# awk 'BEGIN{print ARGV[2]}' /etc/fstab /etc/inittab
/etc/inittab
定义变量name=username在打印$1时引用变量结果如下
[root@localhost ~]# awk -F: '{name="username:";print name,$1}' /data/awktest.txt
username: root
username: bin
username: daemon
username: adm
username: lp
username: sync
username: shutdown
username: halt
username: mail
username: operator
还可以将变量定义在花括号里,并且进记录引用
[root@localhost ~]# awk -F: '{name="username:";print name,$1}' /data/awktest.txt
username: root
username: bin
username: daemon
username: adm
username: lp
username: sync
username: shutdown
username: halt
username: mail
username: operator
甚至我们可以shell中定义变量,在awk当中进记录引用
[root@localhost ~]# username="username:";awk -F: -v name=$username: '{print name,$1}' /data/awktest.txt
username:: root
username:: bin
username:: daemon
username:: adm
username:: lp
username:: sync
username:: shutdown
username:: halt
username:: mail
username:: operator
我们同样可以把awk执记录的命令放进一个文件里面,随后我们可以使用awk -f进记录调用
[root@localhost ~]# echo '{name="sun";age=20;print name,$1,age}' > /data/awkscript
[root@localhost ~]# awk -F: -f /data/awkscript /data/awktest.txt
sun root 20
sun bin 20
sun daemon 20
sun adm 20
sun lp 20
sun sync 20
sun shutdown 20
sun halt 20
sun mail 20
sun operator 20
%c:显示字符的ASCII码;
%d,%i:显示十进制整数;
%e,%E:显示科学计数法数值;
%f:显示为浮点数;
%g,%G:以科学计数法或浮点形式显示数值;
%s:显示字符串;
%u:无符号整数;
%%:显示%自身。
#[.#]:第一个#为数字控制显示的宽度,第二个#表示小数点后的精度,如%3.1f;
-:左对齐(默认右对齐),如%-15s;
+:显示数值的正负号,如%+d。
打印第一个字段,其宽度为20个字符并且换记录,默认是右对齐(%s打印字符)
[root@localhost ~]# awk -F: '{printf "%20s \n",$1}' /data/awktest.txt
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
加-为左对齐打印
[root@localhost ~]#
[root@localhost ~]# awk -F: '{printf "%-20s \n",$1}' /data/awktest.txt
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
打印第三个字符,其宽度为20个字符并且换记录,默认是右对齐(%d,%i打印十进制整数)
[root@localhost ~]# awk -F: '{printf "%20d \n",$3}' /data/awktest.txt
0
1
2
3
4
5
6
7
8
11
加-为左对齐打印
[root@localhost ~]# awk -F: '{printf "%-20d \n",$3}' /data/awktest.txt
0
1
2
3
4
5
6
7
8
11
以分号作为分隔符在username:后打印第一个字段然后换记录
[root@localhost ~]# awk -F: '{printf "username:%s\n",$1}' /data/awktest.txt
username:root
username:bin
username:daemon
username:adm
username:lp
username:sync
username:shutdown
username:halt
username:mail
username:operator
以分号作为分隔符在username:后打印第一个字段,宽度为20个字符左对齐显示,在uid:后打印第三个字段然后换记录
[root@localhost ~]# awk -F: '{printf "username:%-20s uid:%d\n" ,$1,$3}' /data/
awktest.txt
username:root uid:0
username:bin uid:1
username:daemon uid:2
username:adm uid:3
username:lp uid:4
username:sync uid:5
username:shutdown uid:6
username:halt uid:7
username:mail uid:8
username:operator uid:11
x+y:加法;
x-y:减法;
x*y:乘法;
x/y:除法;
x^y:幂运算;
x%y:取模(余数)。
=:右边赋值给左边;
+=:先加,再赋值;
-=:先减,再赋值;
*=:先乘,再赋值;
/=:先除,再赋值;
%=:先取余,再赋值;
^=:先幂运算,再赋值;
++:递增操作;
--:递减操作。
==:判断相等;
!=:判断不等;
>:判断大于;
>=:判断大于等于;
<:判断小于;
<=:判断小于等于。
~:左边是否和右边匹配包含;
!~:是否不匹配。
pattern:根据pattern条件,过滤匹配的记录,再做处理:
1. 如果未指定:空模式,匹配每一记录;
2. /regular expression/:仅处理能够模式匹配到的记录,需要用//扩起来;
3. relational expression:关系表达式,结果为真,才会被处理;
真:结果为非0值,非空字符串都是真;
假:结果为空字符串或0值都是假。
4. line ranges:记录范围;
startine,endline:/pat1/,/pat2/不支持直接给出数子格式。
5. BEGIN/END模式
BEGIN{}:仅在开始处理文件中的文本之前执记录一次;
END{}:仅在文本处理完成之后执记录一次。
1. Expression:算术,比较表达式等;
2. Control statuments:if,while等;
3. conmpound statements:组合语句;
4. input statements:
5. output statements:print等。
&&:逻辑与
||:逻辑或
!:逻辑非
使用awk算数操作符,计算2*3
[root@localhost ~]# awk 'BEGIN{print 2*3}'
6
使用awk算数操作符,对5用2取模
[root@localhost ~]# awk 'BEGIN{print 5%2}'
1
使用awk的+=赋值操作符
root@localhost ~]# awk 'BEGIN{i=10;print i+=1}'
11
使用awk的i++赋值操作符
[root@localhost ~]# awk 'BEGIN{i=10;print i++;print i}'
10
11
使用awk的++i赋值操作符
[root@localhost ~]# awk 'BEGIN{i=10;print ++i}'
11
[root@localhost ~]# awk 'BEGIN{i=10;print ++i;print i}'
11
11
[root@localhost ~]# awk 'BEGIN{i=10;print ++i,i}'
11 11
匹配包含root的记录的记录
[root@localhost ~]# awk -F: '$0 ~ /root/{print}' /data/awktest.txt
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
匹配不包含root的记录的记录
[root@localhost ~]# awk -F: '$0 !~ /root/{print}' /data/awktest.txt
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
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
用正则表达式匹配包含root的记录和以root开头的记录
[root@localhost ~]# awk '/root/{print}' /data/awktest.txt
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost ~]# awk '/^root/{print}' /data/awktest.txt
root:x:0:0:root:/root:/bin/bash
取磁盘利用率
[root@localhost ~]# df -h|grep "/dev/sd"|awk '{print $1,$5}'
/dev/sda2 5%
/dev/sda3 1%
/dev/sda1 17%
[root@localhost ~]# df -h|awk '$0 ~ /^\/dev\/sd/{print $1,$5}'
/dev/sda2 5%
/dev/sda3 1%
/dev/sda1 17%
从hostname.txt⽂件中,提取域名的第⼀部分
[root@localhost ~]# cat /data/hostname.txt
1 magedu.cn.com
2 www.magedu.com
3 mail.magedu.com
[root@localhost ~]# awk -F'[ |.]' '{print $(NF-2)}' /data/hostname.txt
magedu
www
mail
打印第三个字段⼤于等于0,且⼩于等于1000的⾏中的第1字段
[root@localhost ~]# awk -F: '$3>=0 && $3<=1000{print $1}' /data/awktest.txt
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
显⽰第三字段等于0,或⼤于等于1000的⾏中的第1字段
[root@localhost ~]# awk -F: '$3==0 || $3>=1000{print $1}' /data/awktest.txt
root
显⽰除了第三段等于0的⾏中的第1字段
[root@localhost ~]# awk -F: '$3!=0 {print $1}' /data/awktest.txt
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
awk实现打印奇数记录和偶数记录
[root@localhost ~]# seq 10 | awk 'i=!i'
1
3
5
7
9
[root@localhost ~]# seq 10 | awk '!(i=!i)'
2
4
6
8
10
等同于sed打印奇数记录和偶数记录
[root@localhost ~]# seq 10 | sed -n '1~2p'
1
3
5
7
9
[root@localhost ~]# seq 10 | sed -n '2~2p'
2
4
6
8
10
打印/etc/passwd文件中以r开头的的记录的第1个和第3个字段
[root@localhost ~]# awk -F: '/^r/{print $1,$3}' /etc/passwd
root 0
rpc 32
rtkit 172
radvd 75
rpcuser 29
查找netstat -nt命令的结果中Foreign Address列的地址,并显⽰
[root@localhost ~]# netstat -nt|awk '/^tcp/{print $5}'|awk -F: '{print $1}'
172.20.1.11
查找netstat -nt命令的结果中Foreign Address列的地址,统计每个地址链接的次数
[root@localhost ~]# awk '/^f/,/^r/' /etc/passwd
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
libstoragemgmt:x:998:996:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
colord:x:997:995:User for colord:/var/lib/colord:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
注意:如果没有⼀r开头的⾏,则会从匹配的以f开头的⾏开始,到最后都显⽰。
awk的BEGIN/END模式的使⽤
[root@localhost ~]# awk -F: 'BEGIN{print "======================="}{printf "%-10s|%10d |\n",$1,$3}END{print "======================="}' /data/awktest.txt
=======================
root | 0 |
bin | 1 |
daemon | 2 |
adm | 3 |
lp | 4 |
sync | 5 |
shutdown | 6 |
halt | 7 |
mail | 8 |
operator | 11 |
=======================
{statements;...}:组合语句;
if(condition){statements;...}else {statements;...}
if(condition1){statement1}else if(condition2){statement2}
else{statement3}
while(condition){statements;...}
do {statements;...} while(condition)
for(expr1;expr2;expr3) {statements;...}
break
continue
delete array[index]
delete array
exit
显⽰uid⼤于等于500,输出common user,⽤户名和uid,否则输出sysuser
[root@localhost ~]# awk -F: '{$3>=500?usertype="common user":usertype="sysuser";printf "%-15s %-20s %10d\n",usertype,$1,$3}' /etc/passwd
sysuser root 0
sysuser bin 1
...
common user geoclue 991
sysuser pulse 171
common user saned 990
sysuser gdm 42
common user gnome-initial-setup 989
sysuser sshd 74
sysuser avahi 70
sysuser postfix 89
sysuser ntp 38
sysuser tcpdump 72
common user sun 1000
common user apache 799
查找netstat -nt命令的结果中Foreign Address列的地址,统计每个地址链接的次数,如果⼤于2次,显⽰ip
[root@localhost ~]# netstat -nt|awk '/tcp/{print $4}'|awk -F: '{print $1}'|sort|uniq -c|awk '$1>1{print $2}'
模拟并发访问http服务,查找ip连接次数超过200次的访问ip地址 模拟并发:
[root@localhost ~]# yum -y install httpd-tools
[root@localhost ~]# ab -c 10 -n 200 http://172.20.1.69/
显⽰超过200次访问的ip:
[root@localhost ~]# awk '{print $1}' /var/log/httpd/access_log |sort|uniq -c
200 172.20.1.69
[root@localhost ~]# awk '{print $1}' /var/log/httpd/access_log |sort|uniq -c|awk '$1>199{print $2}'
172.20.1.69
显⽰第10条到第20条记录的第1字段
[root@localhost ~]# awk -F: '(NR>=10 && NR<=20){print NR,$1}' /etc/passwd
10 operator
11 games
12 ftp
13 nobody
14 systemd-network
15 dbus
16 polkitd
17 libstoragemgmt
18 colord
19 rpc
20 saslauth
注意:显⽰从第10⾏到第20⾏内容,也可⽤sed命令实现:
[root@localhost ~]# sed -n '10,20p' /etc/passwd
以冒号为分隔符,分别打印第1字段和第3字段
[root@localhost ~]# awk -F: '{print $1;print $3}' /data/awktest.txt
root
0
bin
1
daemon
2
adm
3
lp
4
sync
5
shutdown
6
halt
7
mail
8
operator
11
查找/etc/passwd文件中每个记录第三个字段值大于500的记录,并且打印匹配到的每个记录的第一个字段和第三个字段
[root@localhost ~]# awk -F: '{if($3>=500)print $1,$3}' /etc/passwd
polkitd 999
libstoragemgmt 998
colord 997
saslauth 996
setroubleshoot 995
gluster 994
chrony 993
unbound 992
nfsnobody 65534
geoclue 991
saned 990
gnome-initial-setup 989
sun 1000
apache 799
查找/etc/passwd文件中最后一个字段是/bin/bash的记录,打印符合记录的第一个字段
[root@localhost ~]# awk -F: '{if($0 ~ "/bin/bash")print$1}' /etc/passwd
root
sun
apache
[root@localhost ~]# awk -F: '{if($NF=="/bin/bash")print$1}' /etc/passwd
root
sun
apache
查找/etc/fstab文件中每条记录中字段数大于5的记录,并打印该记录
[root@localhost ~]# awk -F' ' '{if(NR>5)print}' /etc/fstab
# 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=cd2bff96-2cf9-4140-8d08-b1a26f2f5059 / xfs defaults 0 0
UUID=5f1115c9-0c0b-4e1c-a31d-35d4fd099b05 /boot xfs defaults 0 0
UUID=fd2a26b4-8caa-42cf-a78b-8372f7cae188 /data xfs defaults 0 0
UUID=31b99478-3e9f-449a-96af-22213f566f8e swap swap defaults 0 0
查找第3字段⼤于等500,则输出Common user:第1字段,否则输出root or Sysuer:第1字段
第一种
[root@localhost ~]# awk -F: '{if($3>=500){printf "common user:%s\n",$1} else {printf "root or sysuser:%s\n",$1}}' /etc/passwd
第二种
[root@localhost ~]# awk -F: '{$3>=500?usertype="common user:%s\n":usertype="root or sysuser:%s\n";printf usertype, $1}' /etc/passwd
第三种
[root@localhost ~]# awk -F: '{if($3>=500)printf "common user:%s\n",$1;else printf "root or sysuser:%s\n",$1}' /etc/passwd
显⽰磁盘使⽤率⼤于等于8%的分区
[root@localhost ~]# df -h|awk -F% '/^\/dev\/sd/{print $1}'|awk '$NF>=8{print $1,$5}'
/dev/sda1 17
判断awk⾃定义变量test的值,⼤于90则显⽰very good,⼤于60则显⽰good,其它值显⽰no pass
[root@localhost ~]# read -p "please input one number" NUM; awk -v test=$NUM 'BEGIN{if(test>90){print "very good"}else if(test>60){print "good"}else{print "no pass"}}'
do-while循环语法:do {statement;...}while(condition)无论真假,至少执行一次循环体。
for循环语法:for(expr1;expr2;expr3){statement;...}
常见用法:
for(variable assignment;condition;iteration process
{for-body}
特殊用法:
能够遍历数组中的元素:for(var in array){for-body}
语法:switch(expresssion){case VALUE1 or /REGEXP/:statement1;case VALUE2 or
/REGEXP2/:statement2;...;default:statement}
break [n]:结束整个循环默认是最近的一次循环;
continue [n]:跳过本轮循环,执行下一轮循环;
next:提前结束对本行处理而直接进入下一行处理(awk自身循环)。
统计第5⾏内容中每个单词分别有多少个字符
[root@centos6 ~]# sed -n '5p' /etc/grub.conf >> /data/kernel.test
[root@centos6 ~]# awk '{i=1;while(i<=NF){print $i,length($i);++i}}' /data/kernel.test
# 1
all 3
kernel 6
and 3
initrd 6
paths 5
are 3
relative 8
to 2
/boot/, 7
eg. 3
查找最⼤数和最⼩数
[root@centos6 data]# cat /data/NUM.txt
0.234.252.3246.2245.2345.4536.3754.32.345.323.234.3.1
[root@centos6 data]# awk -F. '{min=$1;max=$1;while(i<=NF){if(max<$i)max=$i;if(min>$i)min=$i;i++};print "max:"max,"min:"min}' /data/NUM.txt
max:4536 min:0
或使⽤shell命令实现:
[root@centos6 data]# for i in `tr '.' ' ' < /data/NUM.txt`;do echo $i ; done | sort -n |head
0
1
3
32
234
234
252
323
345
2245
[root@centos6 data]# for i in `tr '.' ' ' < /data/NUM.txt`;do echo $i ; done | sort -n | tail -1
4536
[root@centos6 data]# for i in `tr '.' ' ' < /data/NUM.txt`;do echo $i ; done | sort -n | head -1
0
计算1+2+3+…+100的和
[root@centos6 data]# awk 'BEGIN{i=1;sum=0;while(i<=100){sum+=i;i++};print "sun="sum}'
sun=5050
[root@centos6 data]# read -p "please input one number :" NUM;awk -v num=$NUM 'BEGIN{i=1;sum=0;while(i<=num){sum+=i;i++};print "sum="sum}'
用shell脚本实现
[root@centos6 data]#
[root@centos6 data]# sum=0;for i in {1..100};do let sum+=i;done;echo sum=$sum
sum=5050
使⽤do-while计算100000内的和
[root@centos6 data]# awk 'BEGIN{total=0;i=0;do{total+=i;i++}while(i<=100);print total}'
5050
计算100内整数的和
[root@centos6 data]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++){sum+=i};print sum}'
5050
[root@centos6 data]# time (awk 'BEGIN{total=0;i=0;do{total+=i;i++;}while(i<=100000);print total}')
5000050000
real 0m0.011s
user 0m0.010s
sys 0m0.001s
[root@centos6 data]# time ( sum=0;for i in {1..100000};do let sum+=i;done;echo sum=$sum )
sum=5000050000
real 0m0.779s
user 0m0.528s
sys 0m0.250s
[root@centos6 data]# time ( seq -s "+" 100000|bc )
5000050000
real 0m0.107s
user 0m0.110s
sys 0m0.005s
[root@centos6 data]# time(for((i=0;i<=100000;i++));do let total+=i;done;echo $total)
5000050000
real 0m1.041s
user 0m0.908s
sys 0m0.133s
计算100以内的奇数和
[root@centos6 data]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2==0)continue;sum+=i}print sum}'
2500
计算100以内的偶数和
[root@centos6 data]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2!=0)continue;sum+=i}print sum}'
2550
计算100内的整数和,但遇到整数66就不计算了,退出执⾏
[root@centos6 data]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i==66)break;sum+=i}print sum}'
2145
显⽰uid为偶数⾏的第1字段和第3字段
[root@centos6 data]# awk -F: '{if($3%2!=0)next;print $1,$3}' /etc/passwd
root 0
daemon 2
lp 4
shutdown 6
mail 8
uucp 10
games 12
ftp 14
rpc 32
avahi-autoipd 170
nfsnobody 65534
haldaemon 68
ntp 38
apache 48
saslauth 498
gdm 42
sshd 74
tcpdump 72
sun 500
1. 关联数组:array[index-expression]
2. index-expression:
可使用任意字符串;字符串要使用双引号括起来
如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为空串
若要判断数组中是否存在某元素,要使用index in array格式进行遍历
3. 若要遍历数组中的每个元素,要使用for循环
4. for(var in array){for-body}
5. 注意:var会遍历array的每个索引
创建⼀个weekdays数组,显⽰索引为mon的数组的中的值
[root@centos6 data]# awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";print weekdays["mon"]}'
Monday
使⽤awk中数组去重
[root@centos6 data]# cat abc.txt
a
b
c
aa
bb
cc
a
b
c
[root@centos6 data]# awk '!arr[$0]++' abc.txt
a
b
c
aa
bb
cc
去重的思路演⽰
[root@centos6 data]# awk '{!arr[$0]++;print $0,arr[$0]}' /data/abc.txt 用$0作为下标创建数组arr[$0],但是下标为空(为假),取反之后为真,++为其赋值1
a 1
b 1
c 1
aa 1
bb 1
cc 1
a 2
b 2
c 2
在awk中创建weekdays数组,并添加两个元素
[root@centos6 data]# awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesay";for(i in weekdays){print weekdays[i]}}'
Monday
Tuesay
统计netstat -tan命令结果中各个状态的数量
⽣成TIME-WAIT连接:
[root@centos6 data]# ab -c 10 -n 200 http://172.20.1.69/
统计各个tcp状态的个数:
[root@centos6 data]# ss -tan|awk '!/State/{state[$1]++}END{for(i in state){print i,state[i]}}'
ESTAB 1
LISTEN 10
统计httpd的访问⽇志中每个ip访问的次数
[root@magedu ~]# awk '{ip[$1]++}END{for(i in ip){print i,ip[i]}}' /var/log/httpd/access_log
统计连接本机的ip地址出现的次数
[root@localhost ~]# ss -nt | awk -F '[ :]+' '!/State/{ip[$(NF-2)]++}END{for(i in ip){print i,ip[i]}}'
172.20.1.11 1
或统计访问次数前⼗的ip地址:
[root@localhost ~]# ss -nt|awk -F '[ :]' '!/State/{ip[$(NF-2)++]}END{for(i in ip){print i,ip[i]}}'|sort -nr -k2|head
查找连接本机的次数⼤于20的ip地址,加⼊到防⽕墙禁⽌连接
[root@magedu ~]# ss -nt | awk -F'[ :]+' '!/State/{ip[$(NF-2)]++}END{for(i in ip){print
i,ip[i]}}' | while read line; do ip=`echo $line | awk '{if($2>20)print $1}'`;[ -z "$ip" ]
|| iptables -A INPUT -s $ip -j REJECT; done
或⽤cut简单简单实现:
[root@magedu ~]# ss -nt | awk -F'[ :]' '!/State/{ip[$(NF-2)]++}END{for(i in ip){print
i,ip[i]}}' |while read line; do num=`echo $line | cut -d" " -f2`; ip=`echo $line | cut -d"
" -f1`;[ $num -gt 3 ] && iptables -A INPUT -s $ip -j REJECT; done
[root@localhost ~]# cat /data/socre,txt
name sex score
mage m 100
wang m 90
li f 99
zhao f 95
[root@localhost ~]# awk '!/name/{if($2=="m"){m++;msum+=$3};if($2=="f"){f++;fsum+=$3}}END{print"mavg="msum/m,"favg="fsum/f}' /data/socre,txt
mavg=95 favg=97
或
[root@magedu ~]# awk '!/name/{num[$2]++;sum[$2]+=$3}END{for(i in num){print i "
avg="sum[i]/num[i]}}' socre.txt
m avg=95
f avg=97
rand():返回0和1之间的一个随机数,搭配srand()使用
字
length([s]):返回指定s字符串的长度
sub(r,s[t]):对t字符串进行搜索r表示的模式匹配的内容,并将第一个匹配的内容替换为s
gsub(r,s,[t]):对t字符串进行搜索r表示的模式匹配的内容,并全部替换为s所表示的内容
split(s,array,[r]):以r为分隔符,切割字符串s,并将切割后的结果保存至array所表示的数组中,第一个索引值为1,第二个索引值为2,...
格式:
function name (parameter1, parameter2, ...){
statemenets
return expression
}
⽣成⼀个0到1之间的随机数
[root@magedu ~]# awk 'BEGIN{print rand()}'
0.237788
[root@magedu ~]# awk 'BEGIN{print rand()}'
0.237788
[root@magedu ~]# awk 'BEGIN{print rand()}'
0.237788
[root@magedu ~]# awk 'BEGIN{srand(); print rand()}'
0.792207
[root@magedu ~]# awk 'BEGIN{srand(); print rand()}'
0.046763
[root@magedu ~]# awk 'BEGIN{srand(); print rand()}'
0.046763
或使⽤shell中⽣成随机数的⽅法:
[root@magedu ~]# echo $RANDOM
8149
[root@magedu ~]# echo $RANDOM
29261
[root@magedu ~]# echo $RANDOM
10121
使⽤awk的循环,⽣成10个0-1之间的随机数
[root@magedu ~]# awk 'BEGIN{srand();for(i=0;i<10;i++)print rand()}'
0.90757
0.89926
0.390811
0.546444
0.441346
0.366411
0.17337
0.301543
0.51216
0.883284
使⽤awk的循环,利⽤int函数⽣成10个整数的随机数
[root@magedu ~]# awk 'BEGIN{srand();for(i=0;i<10;i++)print int(rand()*100)}'
1
68
10
71
94
19
77
23
18
83
计算“这是abc”的字符长度
[root@magedu ~]# awk 'BEGIN{print length("这是abc")}'
5
把第⼀个冒号替换成连字符(-)
[root@magedu ~]# echo "2018:08:17 15:47:50" |awk 'sub(/:/,"-",$1)'
2018-08:17 15:47:50
把所有冒号替换成连字符(-)
[root@magedu ~]# echo "2018:08:17 15:47:50" |awk 'gsub(/:/,"-",$0)'
2018-08-17 15-47-50
以冒号为分隔符,分别显⽰每个字段
[root@magedu ~]# echo "2018:08:17 15:47:50" |awk '{split($0,array,":");print array[1]}'
2018
[root@magedu ~]# echo "2018:08:17 15:47:50" |awk '{split($0,array,":");print array[2]}'
08
[root@magedu ~]# echo "2018:08:17 15:47:50" |awk '{split($0,array,":");print array[3]}'
17 15
[root@magedu ~]# echo "2018:08:17 15:47:50" |awk '{split($0,array,":");print array[4]}'
47
[root@magedu ~]# echo "2018:08:17 15:47:50" |awk '{split($0,array,":");print array[5]}'
50
统计连接本机为建⽴状态的ip地址的数量
[root@magedu ~]# netstat -tn|awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for(i in
count){print i,count[i]}}'
172.16.101.234 1
获得两参数的最⼤值,⾃定义函数,在函数内部参数固定
[root@magedu ~]# cat awk.fn
function max(v1,v2){
v1>v2?var=v1:var=v2
return var
}
BEGIN{a=3;b=2;print max(a,b)}
[root@magedu ~]# awk -f awk.fn
3
获得两参数的最⼤值,根据上例,把参数改为可变动的
[root@magedu ~]# cat awk.fn
function max(v1,v2){
v1>v2?var=v1:var=v2
return var
}
BEGIN{print max(a,b)}
[root@magedu ~]# awk -v a=10 -v b=30 -f awk.fn
30
空格是awk中的字符串连接符,如果system中需要使用awk中的变量可以使用空格分隔,或者说除了awk的变量外其
他一律用""引用起来。
将awk程序写成脚本,直接调用或执行
格式:awkfile var1=value1 var2=value2 ... Inputfile
注意:在BEGIN过程中不可使⽤,直到⾸⾏输⼊完成以后,变量才可⽤;可通过-v参数,让awk在执⾏BEGIN之前得到变
量的值;命令⾏中每⼀个指定的变量都需要⼀个-v参数。
在awk中调⽤linux系统的hostname命令
[root@magedu ~]# hostname
magedu
[root@magedu ~]# awk 'BEGIN{system("hostname")}'
magedu
在awk中使⽤linux中echo命令显⽰awk中的变量
[root@magedu ~]# awk 'BEGIN{score=100;system("echo you score is "score)}'
you score is 100
在awk中使⽤iptables命令拒绝来源地址为1.1.1.1的访问
[root@magedu ~]# awk 'BEGIN{ip="1.1.1.1";system("iptables -A INPUT -s " ip " -j REJECT")}'
编写awk脚本,显⽰/etc/passwd中,uid⼤于500的⽤户和uid
[root@magedu ~]# cat f1.awk
#!/bin/awk -f
{if($3>=500)print $1,$3}
[root@magedu ~]# chmod +x f1.awk
[root@magedu ~]# ./f1.awk -F: /etc/passwd
nfsnobody 65534
llj 500
li 501
zhang 502
python 503
显⽰/etc/passwd⽂件中,uid在10-20之间的⽤户名和uid
[root@magedu ~]# cat f2.awk
#!/bin/awk -f
{if($3>=min && $3<=max)print $1,$3}
[root@magedu ~]# chmod +x f2.awk
[root@magedu ~]# ./f2.awk -F: min=10 max=20 /etc/passwd
uucp 10
operator 11
games 12
gopher 13
ftp 14
或使⽤-v参数指定:
[root@magedu ~]# ./f2.awk -F: -v min=10 -v max=20 /etc/passwd
空格是awk中的字符串连接符,如果system中需要使用awk中的变量可以使用空格分隔,或者说除了awk的变量外其
他一律用""引用起来。
将awk程序写成脚本,直接调用或执行
格式:awkfile var1=value1 var2=value2 ... Inputfile
注意:在BEGIN过程中不可使⽤,直到⾸⾏输⼊完成以后,变量才可⽤;可通过-v参数,让awk在执⾏BEGIN之前得到变
量的值;命令⾏中每⼀个指定的变量都需要⼀个-v参数。
在awk中调⽤linux系统的hostname命令
[root@magedu ~]# hostname
magedu
[root@magedu ~]# awk 'BEGIN{system("hostname")}'
magedu
在awk中使⽤linux中echo命令显⽰awk中的变量
[root@magedu ~]# awk 'BEGIN{score=100;system("echo you score is "score)}'
you score is 100
在awk中使⽤iptables命令拒绝来源地址为1.1.1.1的访问
[root@magedu ~]# awk 'BEGIN{ip="1.1.1.1";system("iptables -A INPUT -s " ip " -j REJECT")}'
编写awk脚本,显⽰/etc/passwd中,uid⼤于500的⽤户和uid
[root@magedu ~]# cat f1.awk
#!/bin/awk -f
{if($3>=500)print $1,$3}
[root@magedu ~]# chmod +x f1.awk
[root@magedu ~]# ./f1.awk -F: /etc/passwd
nfsnobody 65534
llj 500
li 501
zhang 502
python 503
显⽰/etc/passwd⽂件中,uid在10-20之间的⽤户名和uid
[root@magedu ~]# cat f2.awk
#!/bin/awk -f
{if($3>=min && $3<=max)print $1,$3}
[root@magedu ~]# chmod +x f2.awk
[root@magedu ~]# ./f2.awk -F: min=10 max=20 /etc/passwd
uucp 10
operator 11
games 12
gopher 13
ftp 14
或使⽤-v参数指定:
[root@magedu ~]# ./f2.awk -F: -v min=10 -v max=20 /etc/passwd