awk作为三剑客之一,其更是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件,或其它命令的输出。
语法结构:
awk 分隔符 'BEGIN{ 动作;… } pattern{ 动作;… } END{ 动作;… }' 文件
BEGIN动作是读文件前执行的,一般用于头文件的生成,pattern部分是读文件的部分,基于文件的行来处理,END是文件读之后的动作,
一般用于总结等。
常用内置变量:
FS:输入字段分割符,类似cut的-d
[root@localhost ~]# awk -v FS=":" '{print $1}' /etc/passwd
root
bin
daemon
adm
lp
.
.
.
说明:以“:”为分隔符,打印/etc/passw的第一个字段,其中 -v FS=“:”和-F效果一样
OFS:输出字段分隔符
[root@localhost ~]# awk -v FS=':' -v OFS='%' '{print $1,$3}' /etc/passwd
root%0
bin%1
daemon%2
adm%3
.
.
.
NF:字段的数量(其是一个int类型的数字),要分清其与$NF
[root@localhost ~]# cat /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
.
.
.
[root@localhost ~]# awk -F: '{print NF}' /etc/passwd
7
7
7
.
.
.
[root@localhost ~]# awk -F: '{print $NF}' /etc/passwd
/bin/bash
/sbin/nologin
/sbin/nologin
.
.
.
说明:NF表示的是字段的数量(被分隔符分割了几段),而$NF也可视其为最后一个字段
NR:记录号,一般都为行号(不改变输入记录分割符的情况下)
[root@localhost ~]# awk -F: '{print NR}' /etc/passwd
1
2
3
.
.
.
变量的定义:
[root@localhost ~]# awk -v tt="hello" '{print tt}' /etc/passwd
hello
hello
hello
.
.
.
[root@localhost ~]# awk '{tt="hello";print tt}' /etc/passwd
hello
hello
hello
.
.
.
格式化输出:
%c: 显示字符的ASCII码
%d, %i: 显示十进制整数
%e, %E:显示科学计数法数值
%f:显示为浮点数
%g, %G:以科学计数法或浮点形式显示数值
%s:显示字符串
%u:无符号整数
%%: 显示%自身
[root@localhost ~]# awk -F: '{printf "%-8s%-8s\n%-8s%s\n","Name","UID",$1,$3}' /etc/passwd
Name UID
root 0
Name UID
bin 1
Name UID
daemon 2
.
.
.
说明:这里打印要用printf其中的%-8s是左对齐方式,其数字可根据需求调整,当打印字符串时用双引号引起来
数字运算:
[root@localhost ~]# awk 'BEGIN{print 2*3}'
6
[root@localhost ~]# awk 'BEGIN{print 2/3}'
0.666667
[root@localhost ~]# awk 'BEGIN{print 2%3}'
2
[root@localhost ~]# awk 'BEGIN{print 2^3}'
8
[root@localhost ~]# awk 'BEGIN{print 2+3}'
5
[root@localhost ~]# awk 'BEGIN{print 2-3}'
-1
模式匹配:支持正则表达式
[root@localhost ~]# awk '$0~/^root/{print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@localhost ~]# awk '$0~/root/{print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost ~]# awk '$0~/root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
说明:$0表示打印匹配到的所有,~/../表示正则部分,注意最后一行命令和倒数第二行的命令,条件后的打印动作可省略,条件成立则打印匹配到的,相反不打印
&&和||和!
[root@localhost ~]# awk -F: '$3>500 && $3<1000{print $3}' /etc/passwd
999
998
997
996
995
994
993
992
991
判断和循环:
[root@localhost ~]# awk -F: '{if($3>500){text="Good"}else{text="just so"}{print $3,text}}' /etc/passwd
0 just so
1 just so
2 just so
3 just so
4 just so
5 just so
6 just so
7 just so
8 just so
11 just so
12 just so
14 just so
99 just so
192 just so
81 just so
999 Good
.
.
.
[root@localhost ~]# awk -F: '{n=1;while(n<NF){print $3,n++}}' /etc/passwd
0 1
0 2
0 3
0 4
0 5
0 6
.
.
.
[root@localhost ~]# awk -F: '{for(i=1;i<NF;i++)print $3,i}' /etc/passwd
0 1
0 2
0 3
0 4
0 5
0 6
.
.
.
数组:
[root@localhost httpd]# awk '{arr[$1]++}END{for(i in arr){print i,arr[i]}}' access_log
192.168.127.1 58
说明:每个ip出现的次数,一般用于报表生成
[root@localhost app]# awk '{for(i=1;i<NF;i++){count[$i]++}}END{for(i in count){print i,count[i]}}' /etc/fstab
mount(8) 1
Aug 1
Accessible 1
pages 1
.
.
.
说明:数组嵌套的使用,来打印/etc/fstab中每个字段出现的次数
函数:
[root@localhost ~]# awk 'BEGIN{print length("hi baby")}' #打印字符的长度
7
[root@localhost ~]# echo "hi baby"|awk 'gsub(/ /,"-",$0)' #替换
hi-baby
[root@localhost ~]# awk 'BEGIN{system("echo hi baby")}' #awk中使用shell命令
hi baby
[root@localhost ~]# awk 'BEGIN{me="marry";system("echo hi baby my name is " me)}'
hi baby my name is marry