一、控制语句
1 if-else语句
使用场景:对awk取得的整行或某个字段做条件判断
语法:
if(condition) statement [else statement]
if(condition1){statement1}else if(condition2){statement 2}else{statement3}
例:判断uid是否大于等于500,是则为普通用户,否则为root或系统用户
]#awk -F: '{if($3>=500){printf "Common User: %-15s,uid %d\n",$1,$3} else {printf "Root or Sysuser: %-15s,uid %i\n",$1,$3}}' /etc/passwd
例:取id为偶数的用户名及UID
例:取出shell为bash的用户
例:判断磁盘的利用率,大于20则给出警告。
]#df -Th |awk -F[%] '/^\/dev\/(sd|ma).*/{print $1}' |awk '{if($NF>=20){printf "Warning,%s usage has %d\n",$1,$NF} }'
2 while循环语句
语法:while(condition) {statements}
条件为真,进入循环;条件为假,退出循环
使用场景:对一行内的多个字段逐一进行类似处理时使用,对数组中的元素逐一处理时使用
例:统计/etc/grub2.cfg文件中以linux16(前面可跟任意个空格)开头的行的每一个单词的字符数
]#awk '/^[[:space:]]*linux16/{num=1;while(num<=NF){print $num,length($num);num++}}' /etc/grub2.cfg
例:在上一个例子的基础上,只显示字符数大于等于7的单词。
]#awk '/^[[:space:]]*linux16/{n=1;while(n<=NF){if(length($n)>=7){print $n,length($n)}n++}}' /etc/grub2.cfg
3 do-while循环语句
语法:do statement while(condition)
无论判断条件为真或假,至少执行一次循环体
]#awk '{do{print "I am the King! "} while($1=="King")}' /etc/passwd
4 for循环语句
语法:for(expr1;expr2;expr3) {statements}
for(变量赋值;条件;变量修正)
例:使用for循环实现统计/etc/grub2.cfg文件中以linux16(前面可跟任意个空格)开头的行的每一个单词的字符数,并只显示字符数大于等于7的
]#awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++){if(length($i)>=7){print $i,length($i)}}}' /etc/grub2.cfg
for的特殊用法:
能够遍历数组中的元素:for(var in array) {for-body}
例:
awk 'BEGIN{test["1st"]="First";test["2nd"]="Second";for(a in test){print test[a]}}'
5 switch语句
语法:switch(expression) {case VALUE1 or /REGEXP1/:statement1;case VALUE2 or /REGEXP2/:statement2;….;default:statement}
例:
]#awk '{switch($3) { case "xfs":print "i am xfs" ; case "ext4":print "i am ext4";default : print "unknown"; }}' /etc/fstab
注:switch语句在CentOS7系列中使用正常,在6中使用会报错误提示。
6 break&continue
break [n]:用于退出循环体,不再执行循环。
在for循环中使用
在while循环中使用
continue:用于退出当次循环,continue后面的循环体不再运行,而是直接进入下一次循环。只能用在for循环体中。
continue用在while循环中,不能正确退出
7 next
用于控制awk的内生循环,提前结束对当前行的处理,直接进入下一行。
例:取出id号为奇数的用户名
]#awk -F: '{if($3%2==0){next}else{print $1,$3}}' /etc/passwd
8、数组
在awk中,所有数组都是关联数组。
关联数组:array[index-expression]
index-expression
1)可使用任意字符串,字符串要使用双引号””
2)如果某数组元素事先不存在,在引用时,awk会自动创建次元素,并将其值初始化为“空串”
若要判断在数组中是否存在某元素,要使用“index in array”格式进行。
若要遍历数组中的每一个元素,需要使用for循环
for(var in array){for-body}
注意:var的值为数组的下标
例:分别统计网络连接中的LISTEN、ESTABLISHED状态的连接数
netstat -tan | awk '/^tcp\>/{state[$NF]++}END{for(i in state){print i,state[i]}}'
ss -tan |awk '/^[LE]/{state[$1]++}END{for(i in state){print i,state[i]}}'
例:
(1)统计/etc/fstab文件中每个文件类型出现的次数
cat /etc/fstab | awk '!/^#/&&!/^$/{fstype[$3]++}END{for(i in fstype){print i,fstype[i]}}'
(2)统计指定文件中每个单词出现的次数
cat /etc/fstab | awk -F[" "=/,"\t"] '{for(i=1;i<=NF;i++){word[$i]++}}END{for(n in word){print n,word[n]}}'
二、函数
内置函数
自定义函数
1、内置函数
数值处理
rand():返回0和1之间的一个随机数
字符串处理
length([s]):返回指定字符串的长度。
split(s,a[,r]):以r为分隔符切割s,并将切割后的结果保存至a所表示的属组中
其数组下标从1开始
例:统计远程连接到当前主机的ip数
netstat -tan | awk '/^tcp\>/{split($5,ip,":");ip_count[ip[1]]++}END{for(i in ip_count) print i,ip_count[i]}'
sub(r,s,[t]) :对t 字符串进行搜索r 表示的模式匹配的内容,并将第一个匹
配的内容替换为s。
例:将/etc/passwd中root用户的用户名替换为superman
将/etc/fstab中ext4的文件类型替换为xfs
gsub(r,s,[t]) :对t 字符串进行搜索r 表示的模式匹配的内容,并全部替换
为s。
例
2、自定义函数
格式:
function name ( parameter, parameter, … ) {
statements
return expression
}
原创文章,作者:M20-1钟明波,如若转载,请注明出处:http://www.178linux.com/48231