AWK控制语句
{ statements;… } 组合语句
if(condition) {statements;…}
if(condition) {statements;…} else {statements;…}
while(conditon) {statments;…}
for(expr1;expr2;expr3) {statements;…}
for(i in arry){for body}
break
continue
next
if语句
-
语法:
- if(condition){statement;…}[else statement]
- if(condition1){statement1}else if(condition2){statement2}else{statement3} 使用场景:
- 对awk取得的整行或某个字段做条件判断
eg:
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
df -h | awk -F% '/^\/dev/{print $1}'|awk '$NF>=80{print $1,$5}'
while循环
-
语法:
- while(condition){statement;…}
条件“真”,进入循环;条件“假”, 退出循环
使用场景:
- 对一行内的多个字段逐一类似处理时使用
对数组中的各元素逐一处理时使用
eg:
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
for循环
-
语法: for(expr1;expr2;expr3) {statement;…}
常见用法:
- for(variable assignment;condition;iteration process){for-body} 特殊用法:
- 能够遍历数组中的元素
语法: for(var in array) {for-body}
eg:
awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print$i,length($i)}}' /etc/grub2.cfg
break和continue
作用:跳出循环和C、shell用法一样
eg:
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}'
next
作用:
提前结束对本行处理而直接进入下一行处理(awk自身循环)
eg:
awk -F: '{if($3%2!=0) next; print $1,$3}' /etc/passwd
awk调用shell命令
-
system命令
- 空格是awk中的字符串连接符,如果system中需要使用awk中的变量可以使用空格分隔,或者说除了awk的变量外其他一律用”“引用起来
eg:
awk 'BEGIN{system("hostname") }'
awk 'BEGIN{score=100; system("echo your scoreis " score) }'
AWK算数运算
awk在算数运算方面和C语音差不多,比shell脚本的语法更加简洁,在action里面直接运算即可
-
算术操作符:
- x+y, x-y, x*y, x/y, x^y, x%y
- -x: 转换为负数
- +x: 转换为数值 字符串操作符:没有符号的操作符,字符串连接
- (1)赋值操作符:
- =, +=, -=, *=, /=, %=, ^=
- ++, –
- (2)比较操作符:
- ==, !=, >, >=, <, <=
- (3)模式匹配符: ~:左边是否和右边匹配包含 !~:是否不匹配
eg:
awk –F: '$0 ~ /root/{print $1}' /etc/passwd
awk '$0~"^root"' /etc/passwd
awk '$0 !~ /root/' /etc/passwd
awk –F: '$3==0' /etc/passwd
-
逻辑操作符: 与&&,或||,非!
- 在awk里没有像shell里的逻辑短路,示例如下:
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
-
条件表达式(三目表达式):
- 语法:selector?if-true-expression:if-false-expression
eg:
awk -F: '{$3>=1000?usertype="Common User":usertype="Sysadmin or SysUser";printf "%15s:%-s\n",$1,usertype}' /etc/passwd
AWK函数
-
自定义函数
- 格式:
function name ( parameter, parameter, … ) {
statements
return expression
}
#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
AWK数组
-
1.关联数组: array[index-expression]
- index-expression:
• 可使用任意字符串;字符串要使用双引号括起来
• 如果某数组元素事先不存在,在引用时, awk会自动创建此元素,并将其值初始化为“空串”
• 若要判断数组中是否存在某元素,要使用“index in array”格式进行遍历
eg:
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
-
2.若要遍历数组中的每个元素,要使用for循环
- for(var in array) {for-body}
注意: var会遍历array的每个索引
eg:
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
AWK脚本
- 将awk程序写成脚本,直接调用或执行(脚本里不用加单引号)
eg:
#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
- 向awk脚本传递参数
-
格式:
- awkfile var=value var2=value2… Inputfile
注意:在BEGIN过程中不可用。直到首行输入完成以后,变量才可用。可以通过-v 参数,让awk在执行BEGIN之前得到变量的值。命令行中每一个指定的变量都需要一个-v参数
eg:
#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