1.基本用法说明
文本处理,输出格式化的文本报表,执行算数运算,执行字符串操作
格式:
awk [options] 'program' var=value file...
awk [options] -f programfile var=value file...
说明:
program通常是被放在单引号中,并可以由三种部分组成
·BEGIN语句块 BEGIN{}:仅在开始处理文件中的文本之前执行一次
·模式匹配的通用语句块
·END语句块 END{}:仅在文本处理完成之后执行一次
常见选项:
-F“分隔符”指明输入时用到的字段分隔符,默认的分隔符是若干个连续空白符
-v var=value 变量赋值
第一步:执行BEGIN{action;...}语句块中的语句
第二步:从文件或标准输入读取一行,然后执行pattern{action;...}语句块,他逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。
第三步:当读至输入流末尾时,执行END{action;...}语句块
BEGIN语句块在awk开始从输入流中读取行之前被执行,这是一个可选的语句块,比如变量初始化,打印输出表格的表头等语句通常可以写在BEGIN语句块中
END语句块在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是一个可选语句块
pattern语句块中的通用命令是最重要的部分,也是可选的。如果没有提供pattern语句块,则默认执行{print},即打印每一个读取到的行,awk读取的每一行都会执行该语句块
分隔符,域和记录
由分隔符分隔的字段标记$1,$2....$n称为域标识,$0为所有域;注意和shell中的变量$符含义不同
文件的每一行称为记录record
如果省略action,则默认执行print$0的操作
2.动作print
格式
print item1,item2,...
说明
逗号分隔符
输出item可以是字符串,也可以是数值;当前记录的字段,变量或awk的表达式
如省略item,相当于print$0
固定字符需要用“”引起来,而变量和数字不需要
范例
[10:09:12 root@centos7 ~]$awk '{print "hello"}'
[10:09:55 root@centos7 ~]$seq 3|awk '{print "hello"}' hello hello hello
[10:11:35 root@centos7 ~]$seq 3|awk '{print 2*3}'
6
6
6
[10:18:37 root@centos7 ~]$awk -F: '{print "yang"}' hi
wang
wang
wang
wang
wang
该文件一共有几行,就打印几个yang
[10:18:39 root@centos7 ~]$awk -F: '{print}' kao
sdad:sdasd:sdjks:sdasd:sdsd
sdsda:sdkaksd:sdkask
ssadsd
sdsd
asdasdad
打印全部内容
[10:20:50 root@centos7 ~]$awk -F: '{print $0}' kao
sdad:sdasd:sdjks:sdasd:sdsd
sdsda:sdkaksd:sdkask
ssadsd
sdsd
asdasdad
加上$0也是打印全部的意思
[10:22:45 root@centos7 ~]$awk -F: '{print $1,$3}' kao
sdad sdjks
sdsda sdkask
ssadsd
sdsd
asdasdad
以冒号为分隔符打印第一行和第三行
[10:23:52 root@centos7 ~]$awk -F: '{print $1" "$3}' kao
sdad sdjks
sdsda sdkask
ssadsd
sdsd
asdasdad
中将用tab隔开
[10:27:34 root@centos7 ~]$grep '^UUID' /etc/fstab |awk '{print $2,$3}'
/boot xfs
默认以空格做分隔符,不限制空格个数
[10:44:22 root@centos7 ~]$df | awk -F"[ %]+" '{print $5}'
Use
0
0
2
0
4
15
1
0
以空隔百分号为分隔符取出分区利用率
[10:50:28 root@centos7 ~]$df | awk -F' +|%' '/^/dev/sd/{print $1,$5}'
/dev/sda1 15
以空隔百分号为分隔符,以/dev/sd开头,取第一列和第五列
[10:58:18 root@centos7 ~]$ifconfig eth0 |awk 'NR==2{print $2}'
10.0.0.7
以空格为分割符取第二行的第二列
[11:15:16 root@centos7 ~]$ifconfig eth0 |awk '/netmask/{print $2}'
10.0.0.7
第二种方法
[11:23:22 root@centos7 ~]$cat host
1 www.ybw.com
2 blog.yang.com
3 study.yang.com
[11:24:23 root@centos7 ~]$awk -F"[ .]" '{print $2}' host
取出.ybw.com前面的主机名部分
3.awk变量
awk中的变量分为:内置和自定义变量
常见内置变量
范例
FS:输入字段分隔符,默认为空白字符
[11:33:37 root@centos7 ~]$awk -v FS=":" '{print $1,FS,$3}' /etc/passwd root : 0 bin : 1 daemon : 2 adm : 3 分隔符为:,引用FS
[11:39:22 root@centos7 ~]$s=:;awk -F$s '{print $1$3}' /etc/passwd
root0
bin1
设变量s=:,在awk里做为分隔符
OFS:输出字段分隔符,默认为空白字符
[11:39:30 root@centos7 ~]$awk -v FS=":" -v OFS="*" '{print $1,$3}' /etc/passwd
root*0
bin*1
daemon*2
OFS:输出字段分隔符,默认为空白字符
NF:字段数量
[11:48:28 root@centos7 ~]$awk -F: '{print NF}' /etc/passwd
7
7
7
显示这一行以冒号分割一共几个字段
[11:51:53 root@centos7 ~]$awk -F: '{print $(NF-1)}' /etc/passwd
/root
/bin
/sbin
显示倒数第二个字段
[14:17:02 root@aiyoubucuo ~]#cat nihao |awk -F"[ :]+" '{print $(NF-2)}'|tail -n +2|sort|uniq -c|sort -nr
12 123.150.181.245
1 114.246.101.61
1 100.100.30.25
取出连接数最多的三个ip
NR:记录编号
[14:19:08 root@aiyoubucuo ~]#cat nihao |awk -F"[ :]+" 'NR!=1{print $(NF-2)}'|sort|uniq -c|sort -nr
12 123.150.181.245
1 114.246.101.61
1 100.100.30.25
同上,NR!==1的意思是除去第一行都取,用来去表头
[14:22:06 root@aiyoubucuo ~]#awk '{print NR,$0}' /etc/passwd
1 root:x:0:0:root:/root:/bin/bash
2 daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
显示行号
FNR:各文件分别计数,记录的编号
[14:27:56 root@centos7 ~]$awk '{print FNR,$0}' /etc/issue /etc/redhat-release
1 S
2 Kernel
on an m
3
1 CentOS Linux release 7.9.2009 (Core)
[14:28:57 root@centos7 ~]$awk '{print NR,$0}' /etc/issue /etc/redhat-release
1 S
2 Kernel
on an m
3
4 CentOS Linux release 7.9.2009 (Core)
FILENAME:当前文件名
[14:37:06 root@centos7 ~]$awk '{print FNR,FILENAME,$0}' /etc/issue /etc/redhat-release
1 /etc/issue S
2 /etc/issue Kernel
on an m
3 /etc/issue
1 /etc/redhat-release CentOS Linux release 7.9.2009 (Core)
4.自定义变量
自定义变量是区分字符大小写的,使用下面方式将进行赋值
-v var=value
[14:37:32 root@centos7 ~]$awk -v test1=test2="hello,gawk" 'BEGIN{print test1,test2}' test2=hello,gawk
5.操作符
[14:54:26 root@centos7 ~]$awk 'BEGIN{i=0;print i++,i}' 0 1 [14:54:36 root@centos7 ~]$awk 'BEGIN{i=0;print ++i,i}' 1 1
n++用法
[14:57:46 root@centos7 ~]$seq 3|awk 'n++'
2
3
n=1时++=2,所以不显示第一行。用来排除行首
[15:01:52 root@centos7 ~]$awk -F: '$3>=1000' /etc/passwd
ybw:x:1000:1000:ybw:/home/ybw:/bin/bash
yang:x:1001:1001::/home/yang:/bin/bash
操作符比较
[15:02:23 root@centos7 ~]$seq 10 |awk 'NR%2==0'
2
4
6
8
10
[15:03:34 root@centos7 ~]$seq 10 |awk 'NR%2==1'
1
3
5
7
9
取奇数,偶数行
逻辑操作符:
与:&&,并且关系
或:||,或者关系
非:!,取反
[15:15:24 root@centos7 ~]$awk -F: '$3>=0 && $3<=1000 {print $1,$3}' /etc/passwd
第三列数字大于等于0,并且小于等于1000
[15:21:48 root@centos7 ~]$awk -F: '$3>=0 || $3<=1000 {print $1,$3}' /etc/passwd
从0到大于1000
[15:21:48 root@centos7 ~]$awk -F: '($3==0) {print $1,$3}' /etc/passwd
只取等于第三列等于0的行
[15:25:50 root@centos7 ~]$awk -F: '!($3==0) {print $1,$3}' /etc/passwd
取反
5.条件判断if-else
[15:49:39 root@centos7 ~]$df | awk -F' +|%' '/^/dev/sd/{if($5>=10)print $1,$5}' /dev/sda1 15
判断以/dev/sd开头行的第5列是否大约10,如果大于则输出$1,$5
6.循环for
[16:13:31 root@centos7 ~]$awk 'BEGIN{sum=0;for(i=1;i<=100;i++){sum+=i};print sum}' 5050
7数组
[16:54:36 root@centos7 ~]$ss -nta |awk 'NR!=1{state[$1]++}END{for (i in state){print i,state[i]}}' LISTEN 5 ESTAB 1
第一列不同的为i,state【i】为这种状态出现的次数