awk [options] 'program' var=value file…
awk [options] -f programfile var=value file…
awk [options] 'BEGIN{ action;… } pattern{ action;… } END{action;… }' file ...
BEGIN是文件一行没有读进来的时候要做的事情或要执行的动作
END当整个文件都处理完之后,要执行的动作比
pattern是每一行要处理的动作
awk 程序通常由:BEGIN语句块、能够使用模式匹配的通用语句块、END语句块,共3部分组成
program通常是被单引号或双引号中
选项
-F 指明输入时用到的字段分隔符
-v var=value: 自定义变量
范例
如果awk不写program则是整行都处理,所以会读入一行执行一个print这个动作
awk默认是读取标准输出的,所以我们可以用管道传给awk
这里一定要注意,只要是字符串一定要拿双引号引起来 也可以做数字运算,数字不用加双引号
取出/etc/passwd文件的第3列 取出磁盘利用率也是很方便的,awk默认是以空格为分隔符的。也可取多个字段,也可自定义格式
[root@centos6 app]# df | grep /dev/sd| awk '{print $1,$5}'
/dev/sda2 10%
/dev/sda3 1%
/dev/sda1 4%
[root@centos6 app]# df | grep /dev/sd| awk '{print $1"===="$5}'
/dev/sda2====10%
/dev/sda3====1%
/dev/sda1====4%
awk '{print "hello,awk"}'
awk –F: '{print}' /etc/passwd
awk –F: '{print "wang"}' /etc/passwd
awk –F: '{print $1}' /etc/passwd
awk –F: '{print $0}' /etc/passwd
awk –F: '{print $1"\t"$3}' /etc/passwd
tail –3 /etc/fstab |awk '{print $2,$4}'
awk -v FS=':' '{print $1,FS,$3}' /etc/passwd
awk –F: '{print $1,$3,$7}' /etc/passwd
这两种写法是等价的
因为FS是一个变量,所有我们可以引用这个变量,而-F是一个选项,不能被引用
[root@centos6 app]# awk -v FS=":" '{print $1,FS,$4}' /etc/passwd
root : 0
bin : 1
daemon : 2
adm : 4
lp : 7
sync : 0
shutdown : 0
halt : 0
mail : 12
uucp : 14
operator : 0
games : 100
gopher : 30
ftp : 50
nobody : 99
dbus : 81
usbmuxd : 113
FS也可以引用bash变量
[root@centos6 app]# i=":" ; awk -v FS="$i" '{ print $1,FS,$3 }' /etc/passwd
root : 0
bin : 1
daemon : 2
adm : 3
lp : 4
sync : 5
shutdown : 6
halt : 7
mail : 8
-F也是可以调用shell变量的,只是里面不能使用了
[root@centos6 app]# i=":" ; awk -F "$i" '{ print $1,:,$3 }' /etc/passwd
awk -v FS=':' -v OFS=':' '{print $1,$3,$7}' /etc/passwd
逗号默认输出是空格为分隔符,我们也可以定义显示的分隔符
[root@centos6 app]# awk -v FS=":" -v OFS="+" '{print $1,$3}' /etc/passwd
root+0
bin+1
daemon+2
adm+3
lp+4
sync+5
shutdown+6
halt+7
mail+8
awk -v RS=' ' '{print }' /etc/passwd
比如,
vim f1.txt
1 2 3;4 5 6;7
8 9
如果我们以分号为分隔符,这这里就是3行记录
[root@centos6 app]# awk -v RS=";" '{print $2}' f1.txt
2
5
8
默认是以空白符分隔字段,我们打印第2个字段所有是258是三行记录
===================
[root@centos6 app]# cat f2
a
b
c dd
ff
gg aaa
qq
ww
eee ccc
这文件如果我们以空格为记录分隔符,取第1个字段和第2个字段的结果是什么
[root@centos6 app]# awk -v RS=" " '{print $1,$2}' f2
a b
dd ff
aaa qq
ccc
结果是这样的,所有回车换行并不是空白符
awk -v RS=' ' -v ORS='###''{print }' /etc/passwd
[root@centos6 app]# awk -v ORS="====" -v RS=" " '{print $1,$2}' f2
a b====dd ff====aaa qq====ccc ====[root@centos6 app]#
awk -F: '{print NF}' /etc/fstab,引用内置变量不用$
awk -F: '{print $(NF-1)}' /etc/passwd
[root@centos6 app]# awk -F : '{print NF}' /etc/passwd
7
7
7
7
7
[root@centos6 app]# awk -F : '{print $NF}' /etc/passwd $NF表示最后一个字段
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
[root@centos6 app]# awk -F : '{print $(NF-1)}' /etc/passwd
/root
[root@centos6 app]# df |awk '{print $(NF-1)}'|awk -F % '{print $1}'
Mounted
10
1
1
4
100
[root@centos6 app]#
awk '{print NR}' /etc/fstab ; awk END'{print NR}' /etc/fstab
[root@centos6 app]# awk '{print NR $0}' /etc/fstab
1
2#
3# /etc/fstab
4# Created by anaconda on Tue Nov 7 15:42:36 2017
5#
6# Accessible filesystems, by reference, are maintained under '/dev/disk'
7# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
8#
9UUID=03352018-7cef-4ee3-9a05-b0833b67da19 / ext4 defaults 1 1
10UUID=0bd51fa6-f577-427a-b0b2-1cb8a631ac16 /app ext4 defaults 1 2
11UUID=bbfd63dd-da18-4ac9-affd-4724c571db21 /boot ext4 defaults 1 2
12UUID=a8c19a79-3c21-4aa4-a648-27a069f25bde swap swap defaults 0 0
也可以后面跟多个文件,awk会认为把多个文件当成一个文件开始计算行号
[root@centos6 app]# awk '{print NR $0}' /etc/fstab /etc/issue
1
2#
3# /etc/fstab
4# Created by anaconda on Tue Nov 7 15:42:36 2017
5#
6# Accessible filesystems, by reference, are maintained under '/dev/disk'
7# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
8#
9UUID=03352018-7cef-4ee3-9a05-b0833b67da19 / ext4 defaults 1 1
10UUID=0bd51fa6-f577-427a-b0b2-1cb8a631ac16 /app ext4 defaults 1 2
11UUID=bbfd63dd-da18-4ac9-affd-4724c571db21 /boot ext4 defaults 1 2
12UUID=a8c19a79-3c21-4aa4-a648-27a069f25bde swap swap defaults 0 0
13tmpfs /dev/shm tmpfs defaults 0 0
14devpts /dev/pts devpts gid=5,mode=620 0 0
15sysfs /sys sysfs defaults 0 0
16proc /proc proc defaults 0 0
17/dev/cdrom /mnt iso9660 defaults 0 0
18CentOS release 6.9 (Final)
19Kernel \r on an \m
20
awk '{print FNR}' /etc/fstab /etc/inittab
[root@centos6 app]# awk '{print FNR $0}' /etc/fstab /etc/issue
1
2#
3# /etc/fstab
4# Created by anaconda on Tue Nov 7 15:42:36 2017
5#
6# Accessible filesystems, by reference, are maintained under '/dev/disk'
7# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
8#
9UUID=03352018-7cef-4ee3-9a05-b0833b67da19 / ext4 defaults 1 1
10UUID=0bd51fa6-f577-427a-b0b2-1cb8a631ac16 /app ext4 defaults 1 2
11UUID=bbfd63dd-da18-4ac9-affd-4724c571db21 /boot ext4 defaults 1 2
12UUID=a8c19a79-3c21-4aa4-a648-27a069f25bde swap swap defaults 0 0
13tmpfs /dev/shm tmpfs defaults 0 0
14devpts /dev/pts devpts gid=5,mode=620 0 0
15sysfs /sys sysfs defaults 0 0
16proc /proc proc defaults 0 0
17/dev/cdrom /mnt iso9660 defaults 0 0
1CentOS release 6.9 (Final)
2Kernel \r on an \m
3
awk '{print FILENAME}' /etc/fstab
[root@centos6 app]# awk '{print FILENAME,$0}' /etc/issue
/etc/issue CentOS release 6.9 (Final)
/etc/issue Kernel \r on an \m
/etc/issue
awk '{print ARGC}' /etc/fstab /etc/inittab
awk 'BEGIN {print ARGC}' /etc/fstab /etc/inittab
[root@centos6 app]# awk '{print ARGC}' /etc/fstab /etc/issue
3
3
3
3
3
awk 'BEGIN {print ARGV[0]}' /etc/fstab /etc/inittab
awk 'BEGIN {print ARGV[1]}' /etc/fstab /etc/inittab
[root@centos6 app]# awk '{print ARGV[0]}' /etc/fstab /etc/issue
awk
awk
awk
awk
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
======也可将常用的程序写到文件中用-f调用======
cat awkscript
{print script,$1,$2}
awk -F: -f awkscript script="awk" /etc/passwd
[root@centos6 app]# cat awk.txt
{user="usernam";uid="uid";print user"="$1,uid"="$3}
[root@centos6 app]# awk -F: -f awk.txt /etc/passwd
usernam=root uid=0
usernam=bin uid=1
usernam=daemon uid=2
usernam=adm uid=3
usernam=lp uid=4
==========
[root@centos6 app]# awk -v user="username" -v uid="uid" -F: '{print user"="$1,uid"="$3}' /etc/passwd
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
[root@centos6 app]# awk -v uid="uid" -F: '{user="username";print user"="$1,uid"="$3}' /etc/passwd //也可以在程序里定义变量,在程序里定义变量就不能调用shell里的变量
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
userame=mail uid=8
username=uucp uid=10
[root@centos6 app]# u=username; awk -v user=$u -v uid=uid -F: '{print user"="$1,uid"="$3}' /etc/passwd
username=root uid=0
username=bin uid=1
username=daemon uid=2
username=adm uid=3
格式符:与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: %s,UID:%d\n",$1,$3}' /etc/passwd
awk -F: '{printf "Username: %15s,UID:%d\n",$1,$3}' /etc/passwd
awk -F: '{printf "Username: %-15s,UID:%d\n",$1,$3}' /etc/passwd
[root@centos6 app]# awk -F: '{printf "%s:%d\n",$1,$3}' /etc/passwd
root:0
bin:1
daemon:2
adm:3
lp:4
sync:5
shutdown:6
halt:7
mail:8
uucp:10
operator:11
[root@centos6 app]# awk -F: '{printf "%-30s%d\n",$1,$3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
[root@centos6 app]# awk -F: '{printf "%-30s| %d\n",$1,$3}' /etc/passwd
root | 0
bin | 1
daemon | 2
adm | 3
lp | 4
sync | 5
shutdown | 6
halt | 7
[root@centos6 app]# awk -v n=123.4567 '{printf "%8.4f\n",n }' /etc/fstab //这里n的值加小数点一共8位,所有我们第一个8是总长度,小数点之后的是4位
123.4567
123.4567
123.4567
123.4567
123.4567
[root@centos6 app]# awk -v n=123.4567 '{printf "%8.3f\n",n }' /etc/fstab 这个意思是小数点之后是3位说以最后一位7被四舍五入了,但是前面多一个空格,代表一共是8位
123.457
123.457
123.457
123.457
123.457
123.457
123.457
因为这里打印多行是文件有几行就打印几行,我们可以用BEGIN,可以不用跟文件就打印一次
[root@centos6 app]# awk -v n=123.4567 'BEGIN{printf "%8.3f\n",n }'
123.457
[root@centos6 app]# awk -v n=123.4567 'BEGIN{printf "%10.3f\n",n }'
123.457
x+y, x-y, x*y, x/y, x^y, x%y
[root@centos6 app]# awk -v n=10 -v m=3 'BEGIN{print n%m}'
1
-x: 转换为负数
+x: 转换为数值
- 字符串操作符:没有符号的操作符,字符串连接
- 赋值操作符
=, +=, -=, *=, /=, %=, ^=
++, --
[root@centos6 app]# awk -v n=10 -v m=3 'BEGIN{print m+=n}'
13
[root@centos6 app]# awk -v n=10 -v m=3 'BEGIN{print m+=n,m++,m}' 这个是m++是先读取在自+
13 13 14
[root@centos6 app]# awk -v n=10 -v m=3 'BEGIN{print m+=n,++m,m}'
13 14 14
下面两语句有何不同
awk 'BEGIN{i=0;print ++i,i}'
[root@centos6 app]# awk 'BEGIN{i=0;print ++i,i}'
1 1
awk 'BEGIN{i=0;print i++,i}'
[root@centos6 app]# awk 'BEGIN{i=0;print i++,i}'
0 1
==, !=, >, >=, <, <=
~:左边是否和右边匹配包含只要包含就匹配 !~:是否不匹配
awk –F: '$0 ~ /root/{print $1}' /etc/passwd
awk '$0~“^root"' /etc/passwd
awk '$0 !~ /root/' /etc/passwd
awk –F: '$3==0' /etc/passwd
[root@centos6 app]# awk '$0~"^root"' /etc/passwd awk如果不写花括号,模式是print $0打印整行
root:x:0:0:root:/root:/bin/bash
[root@centos6 app]# awk '$0 ~ /^bin/' /etc/passwd 正则表达式是要放在两个斜线之前的
bin:x:1:1:bin:/bin:/sbin/nologin
[root@centos6 app]# awk -F: '$3==0' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@centos6 app]# awk -F: '$3>=500' /etc/passwd 这里相当于每读入一行就判断
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
guo:x:500:500::/home/guo:/bin/bash
[root@centos6 app]#
============================
[root@centos6 app]# awk -v i= "i" /etc/issue i没有赋值是假
[root@centos6 app]# awk -v i="" "i" /etc/issue 这样也是假
[root@centos6 app]# awk -v i=0 "i" /etc/issue i等于0也是假
[root@centos6 app]# awk -v i=" " "i" /etc/issue i等于空是真,打印全部内容
CentOS release 6.9 (Final)
Kernel \r on an \m
只要不是0,空,或没有定义,都算真,负数也算真
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
[root@centos6 app]# awk -F: -v i=10 'i' /etc/issue
CentOS release 6.9 (Final)
Kernel \r on an \m
[root@centos6 app]# awk -F: -v i=10 '!i' /etc/issue
[root@centos6 app]# awk -F: -v i=10 '{print i}' /etc/issue
10
10
10
[root@centos6 app]# awk -F: -v i=10 '{print !i}' /etc/issue
0
0
0
假取反就是真
[root@centos6 app]# awk '{i=0;print !i++,i}' /etc/issue 先取反打印,然后在运算
1 1
1 1
1 1
[root@centos6 app]# awk '{i=-1;print !i++,i}' /etc/issue
0 0
0 0
0 0
[root@centos6 app]# awk '{i=0;print !++i,i}' /etc/issue 先运算++,得出的数值在取反
0 1
0 1
0 1
[root@centos6 app]# awk '{i=-1;print !++i,i}' /etc/issue
1 0
1 0
1 0
awk -F: '{$3>=1000?usertype="Common User":usertype="Sysadmin or SysUser";printf "%15s:%-s\n",$1,usertype}' /etc/passwd
[root@centos6 app]# awk -F: '{$3>=500?usertype="common user":usertype="sysuser" ;printf "%15s %30s %d \n", usertype,$1,$3 }' /etc/passwd
sysuser root 0
sysuser bin 1
sysuser daemon 2
sysuser adm 3
sysuser lp 4
sysuser sync 5
sysuser shutdown 6
sysuser halt 7
sysuser mail 8
sysuser uucp 10
sysuser operator 11
sysuser games 12
sysuser gopher 13
sysuser ftp 14
sysuser nobody 99
sysuser dbus 81
sysuser usbmuxd 113
sysuser rpc 32
sysuser rtkit 499
sysuser avahi-autoipd 170
sysuser vcsa 69
sysuser abrt 173
sysuser rpcuser 29
common user nfsnobody 65534
sysuser haldaemon 68
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
取奇数行和偶数行
[root@centos6 app]# seq 10 | sed -n '1~2p'
1
3
5
7
9
[root@centos6 app]# seq 10 | sed -n '2~2p'
2
4
6
8
10
用awk来取奇数和偶数行
[root@centos6 app]# seq 10 | awk 'i=!i' 因为i为假,然后对i取反就是真那么第一行就是真打印第一行,当读入第2行时i已经是真了,所以i取反为假就不打印第2行
1
3
5
7
9
[root@centos6 app]# seq 10 |awk -v i=11 'i=!i'
2
4
6
8
10
[root@centos6 app]# seq 10 |awk '!(i=!i)'
2
4
6
8
10
startline,endline:/pat1/,/pat2/ 不支持直接给出数字格式
awk -F: '/^root\>/,/^nobody\>/{print $1}' /etc/passwd
awk -F: '(NR>=10&&NR<=20){print NR,$1}' /etc/passwd
[root@centos6 app]# awk '/^f/,/^r/' /etc/passwd 首先找到第一pat1是开始显示,一直找到pat2结束
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
sed如何显示从第几行到第几行
[root@centos6 app]# seq 10 | sed -n '2,5p'
2
3
4
5
awk如何显示从第几行到第几行
[root@centos6 app]# seq 10 | awk 'NR>=2&&NR<=5'
2
3
4
5
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
awk -F: 'BEGIN{print " USER UID \n---------------"}{print $1,$3}' /etc/passwd
awk -F: 'BEGIN{print " USER UID \n---------------"}{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@centos6 app]# awk -F: 'BEGIN{printf "USERNAEM UDI\n=================================\n"}{printf "%-30s %d\n",$1,$3}' /etc/passwd
USERNAEM UDI
=================================
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
uucp 10
operator 1
guo 500
[root@centos6 app]# awk -F: 'BEGIN{printf "=================================\nUSERNAEM UDI\n=================================\n"}{printf "%-30s %d\n",$1,$3}' /etc/passwd
=================================
USERNAEM UDI
=================================
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
uucp 10
operator 11
[root@centos6 app]# awk -F: 'BEGIN{printf "=================================\nUSERNAEM | UDI\n=================================\n"}{printf "|%-30s | %d\n=================================\n",$1,$3}' /etc/passwd
=================================
USERNAEM | UDI
=================================
|root | 0
=================================
|bin | 1
=================================
|daemon | 2
=================================
|adm | 3
=================================
|lp | 4
=================================
|sync | 5
语法
if(condition){statement;…}[else statement]
if(condition1){statement1}else if(condition2){statement2} else{statement3}
- 使用场景:对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/fstab
awk -F: '{if($3>=1000) {printf "Common user: %s\n",$1} else{printf "root or Sysuser: %s\n",$1}}' /etc/passwd
awk -F: '{if($3>=1000) printf "Common user: %s\n",$1;else printf "root or Sysuser: %s\n",$1}' /etc/passwd
df -h|awk -F% '/^\/dev/{print $1}'|awk '$NF>=80{print $1,$5}'
awk 'BEGIN{ test=100;if(test>90){print "very good"} else if(test>60){ print "good"}else{print "no pass"}}'
[root@centos6 app]# awk -F: '{if ($3>=500){usertype="common user" ;print usertype,$1,$3}}' /etc/passwd
common user nfsnobody 65534
common user guo 500
取出分区利用率
[root@centos6 app]# df | awk '/^\/dev\/sd/{print $1,$(NF-1)}'
/dev/sda2 10%
/dev/sda3 1%
/dev/sda1 4%
[root@centos6 app]# df | awk '{if($0~/^\/dev\/sd/)print $1,$(NF-1)}'
/dev/sda2 10%
/dev/sda3 1%
/dev/sda1 4%
取当分区利用率大于多少时取出对应的设备名
[root@centos6 app]# df | awk -F% '/^\/dev\/sd/{print $(NF-1)}'|awk '{if($NF>=10)print $1,$NF}'
/dev/sda2 10
也可以使用用多个分隔符
[root@centos6 app]# df | awk -F "[ %]+" '/^\/dev\/sd/{print $1,$5}'
/dev/sda2 10
/dev/sda3 1
/dev/sda1 4
[root@centos6 app]# awk -F: '{print $1,length($1)}' /etc/passwd
root 4
bin 3
daemon 6
adm 3
lp 2
sync 4
shutdown 8
halt 4
mail 4
uucp 4
operator 8
games 5
gopher 6
ftp 3
在shell中如何判断字符数
[root@centos6 app]# v=hahah
[root@centos6 app]# echo ${#v}
5
判断root这一行每个字段各是多少个字符
[root@centos6 app]# awk -F: '/^root/{i=1;while(i<=NF){print $i ,length($i);i++}}' /etc/passwd
root 4
x 1
0 1
0 1
root 4
/root 5
/bin/bash 9
如何用awk语句从1加到100之和
[root@centos6 app]# awk 'BEGIN{i=1;sum=0;while(i<=100){sum+=i;i++}print sum}'
5050
[root@centos6 app]# awk 'BEGIN{i=1;sum=0;do{sum+=i;i++}while(i<=100)print sum}'
5050
[root@centos6 app]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++)sum+=i;print sum}'
5050
用seq计算1到100之和
[root@centos6 app]# seq -s+ 1 100 |bc
5050
示例
awk '/^[[:space:]]*linux16/{i=1;while(i<=NF){print $i,length($i); i++}}' /etc/grub2.cfg
awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=10){print $i,length($i)}; i++}}' /etc/grub2.cfg
示例
awk 'BEGIN{ total=0;i=0;do{total+=i;i++;}while(i<=100);print total}'
for(variable assignment;condition;iteration process){for-body}
示例
awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /etc/grub2.cfg
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)
[root@centos6 app]# time awk 'BEGIN{sum=0;for(i=1;i<=10000000;i++)sum+=i;print sum}'
50000005000000
real 0m0.923s
user 0m0.921s
sys 0m0.002s
这里时间第一个时间表示一共使用多长时间
第2个是用户空间使用时间
第3个系统使用空间
switch(expression) {case VALUE1 or /REGEXP/: statement1; case VALUE2 or /REGEXP2/: statement2;...; default: statementn}
awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2==0)continue;sum+=i}print sum}'
awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i==66)break;sum+=i}print sum}'
[root@centos6 app]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2!=0)continue ;sum+=i}print sum}'
2550
[root@centos6 app]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i==50)break;sum+=i}print sum}'
1225
只对奇数行进行处理
[root@centos6 app]# awk -F: '{if($3%2!=1)next;print $1,$3}' /etc/passwd
bin 1
adm 3
sync 5
halt 7
operator 11
gopher 13
nobody 99
示例
weekdays[“mon”]="Monday"
awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";print weekdays["mon"]}'
awk '!arr[$0]++' dupfile
awk '{!arr[$0]++;print $0, arr[$0]}' dupfile
用awk把文件中重复的行去掉
[root@centos6 app]# cat aaa
aaaa
bbbb
cccc
aaaaaa
aaaa
bbbb
ddddd
aa
ddddd
[root@centos6 app]# awk '!arr[$0]++' aaa
aaaa
bbbb
cccc
aaaaaa
ddddd
shell去重复行方法
[root@centos6 app]# sort aaa | uniq
aa
aaaa
aaaaaa
bbbb
cccc
ddddd
示例
awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";for(i in weekdays) {print weekdays[i]}}'
netstat -tan | awk '/^tcp/{state[$NF]++}END
{for(i in state) { print i,state[i]}}'
awk '{ip[$1]++}END{for(i in ip) {print i,ip[i]}}'
/var/log/httpd/access_log
[root@centos6 app]# netstat -nta | awk '/^tcp/{state[$NF]++}END{for(i in state){print i,state[i]}}'
ESTABLISHED 1
LISTEN 11
查找日志中的ip链接数和对应ip
[root@centos6 app]# awk '{ip[$1]++}END{for(i in ip){print i,ip[i]}}' access_log
172.18.56.3 159091
192.168.27.6 4004
172.18.0.100 24
分析日志中链接数大于1000次的ip并加入到IPtables中
[root@centos6 app]# awk '{ip[$1]++}END{for(i in ip)if(ip[i]>1000){print i}}' access_log |while read l ;do iptables -A INPUT -s $l -j REJECT; done
分析会话链接数前十个的ip
[root@centos6 app]# ss -nt|awk '/^ESTAB/{print $NF}'|awk -F: '{print $1}'|sort|uniq -c | sort -nr | head -n3
分析会话链接数前十个的ip并加入iptables中
[root@centos6 app]# ss -nt|awk '/^ESTAB/{print $NF}'|awk -F: '{print $1}'|sort|uniq -c | sort -nr | head -n3 | while read coo ip;do iptables -A INPUT -s $ip -j REJECT;done
awk 'BEGIN{srand(); for (i=1;i<=10;i++)print int(rand()*100) }'
[root@centos6 app]# awk 'BEGIN{print rand()}' //如果直接这样写会固定值不变,要想生成随机数需要调用另一个函数srand()
0.237788
[root@centos6 app]# awk 'BEGIN{print rand()}'
0.237788
[root@centos6 app]# awk 'BEGIN{print rand()}'
0.237788
[root@centos6 app]# awk 'BEGIN{srand();print rand()}' 这样就生成随机数,
0.434576
[root@centos6 app]# awk 'BEGIN{srand();print rand()}'
0.510123
[root@centos6 app]# awk 'BEGIN{srand();print rand()*10}' 我们可以成*10或更大
3.07812
[root@centos6 app]# awk 'BEGIN{srand();print int(rand()*10)}'加上int就是取整数
8
[root@centos6 app]# awk 'BEGIN{srand();print int(rand()*100)}'
77
[root@centos6 app]# awk 'BEGIN{srand();print int(rand()*100)}'
17
echo "2008:08:08 08:08:08" | awk 'sub(/:/,"-",$1)'
[root@centos6 app]# echo "2008:08:08 08:08:08" | awk 'sub(/:/,"-",$1)' sub默认只替代第一个匹配的
2008-08:08 08:08:08
[root@centos6 app]# echo "2008:08:08 08:08:08" | awk 'gsub(/:/,"-",$1)' gsub会把整个字段都匹配,因为默认是以空白符分隔所以2008:08:08是第一个字段
2008-08-08 08:08:08
[root@centos6 app]# echo "2008:08:08 08:08:08" | awk 'gsub(/:/,"-",$0)' 可以用$0整行匹配
2008-08-08 08-08-08
- gsub(r,s,[t]):对t字符串进行搜索r表示的模式匹配的内容,并全部替换为s所表示的内容
echo "2008:08:08 08:08:08" | awk ‘gsub(/:/,“-",$0)'
- split(s,array,[r]):以r为分隔符,切割字符串s,并将切割后的结果保存至array所表示的数组中,第一个索引值为1,第二个索引值为2,…
netstat -tan | awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++}
END{for (i in count) {print i,count[i]}}'
[root@centos6 app]# echo "2008:01:02 03:04:05" | awk '{split($0,str,":")}END{for(i in str){print i,str[i]}}' 这是以冒号为分隔符,生成一个数组str,是整行分割,str数组下标1的值是2008
4 04
5 05
1 2008
2 01
3 02 03
统计文件中每个单词出现的次数
[root@1234 ~]# awk '{for(i=1;i<=NF;i++)word[$i]++}END{for(i in word)print word[i],i}' /etc/profile | sort -nr
13 #
9 [
8 then
8 if
如何用awk显示男生,女的总成绩,和平均值
[root@1234 ~]# vim f1
li 85 female
guo 100 male
zhang 90 male
wang 99 female
li 85 female
[root@1234 ~]# awk '{if($3=="male"){mnum++;msun+=$2}else{fnun++;fsum+=$2}}END{printf "male:%d %5.2f\nfemale:%d %5.2f\n",mnum,msun/mnum,fnun,fsum/fnun}' f1
male:2 95.00
female:2 92.00
用数组的方法
[root@1234 ~]# awk '{num[$3]++;sum[$3]+=$2}END{for(sex in num)print sex,num[sex],sum[sex]/num[sex]}' f1
female 2 92
male 2 95
格式
function name ( parameter, parameter, ... ) {
statements
return expression
}
( parameter, parameter, ... ) 这里面的表示是参数,位置参数
示例
cat fun.awk
function max(v1,v2) {
v1>v2?var=v1:var=v2
return var
}
BEGIN{a=3;b=2;print max(a,b)}
awk –f fun.awk
这个函数表示max(v1,v2)是形式上的参数,是没有任何赋值的,只是代表着位置参数,而BEGIN{a=3;b=2;print max(a,b)}a,b是实际的参数,形式的参数和实际的参数可以名字不一样,但是数量上一定要相等。
v1>v2?var=v1:var=v2 这是是要执行的程序
return var :return这个必须要写,要返回一个值
文件里的不用加单引号
awk 用-f 调用这个函数
[root@1234 ~]# vim fun.awk
function max(v1,v2) {
v1>v2?var=v1:var=v2
return var
}
BEGIN {a=3;b=2;print max(a,b)}
[root@1234 ~]# awk -f fun.awk
3
[root@1234 ~]# vim fun.awk
function max(v1,v2) {
v1>v2?var=v1:var=v2
return var
}
BEGIN {print max(a,b)}
[root@1234 ~]# awk -v a=20 -v b=30 -f fun.awk
30
awk BEGIN'{system("hostname") }'
awk 'BEGIN{score=100; system("echo your score is " score) }'
[root@1234 ~]# awk 'BEGIN{system("hostname")}'
1234
[root@1234 ~]# awk 'BEGIN{i=10;system("echo i ")}'
i
[root@1234 ~]# awk 'BEGIN{i=10;system("echo"i)}' 这里的echo没有空格所以报语法错误
sh: echo10: command not found
[root@1234 ~]# awk 'BEGIN{i=10;system("echo "i)}'
10
[root@1234 ~]# vim fun.awk
#!/bin/awk -f
function max(v1,v2) {
v1>v2?var=v1:var=v2
return var
}
BEGIN {print max(a,b)}
[root@1234 ~]# chmod +x fun.awk
[root@1234 ~]# ./fun.awk -v a=10 -v b=20
20
示例
cat f1.awk
{if($3>=1000)print $1,$3}
awk -F: -f f1.awk /etc/passwd
cat f2.awk
#!/bin/awk –f
#this is a awk script
{if($3>=1000)print $1,$3}
# chmod +x f2.awk
f2.awk –F: /etc/passwd
示例
cat test.awk
#!/bin/awk –f
{if($3 >=min && $3<=max)print $1,$3}
chmod +x test.awk
test.awk -F: min=100 max=200 /etc/passwd