awk基本用法:
awk [options] ‘program’ file1 file2
program: PATTERN{ ACTION STATEMENT }由语句组成,语句分隔符是分号
ACTION: print ,printf
选项:-F:指明输入字段分隔符
-v var=value: 变量赋值
一、awk的输出命令print
print item1,item2, ...
要点:
(1) 各item间使用逗号分隔,而输出时则使用输出分隔符分隔;
(2) 输出的各item可以字符串或数值、当前记录的字段($n)、变量或awk的表达式;数值会被隐式转换为字符进行输出;
(3) print后面的item如果省略,相当于print$0; 输出“空白”,使用print"";
二、变量
1、内置变量
FS:输入分隔符,默认为空白字符
RS:The input recordseparator默认为换行符
OFS:The output field separator,默认为空白字符
ORS: The output record separator,默认为换行符
NF:字段数
NR:行数,所有文件统一计数
FNR:行数,各文件分别计数
FILENAME:当前文件名
ARGC:命令行参数的个数
ARGV:命令行参数数组
2、自定义变量
-v var=value:变量名区分字符大小写
(1)可以在program中定义变量
(2)通过-v选项定义变量
三、printf命令
格式:printf formatitem1,item2
要点:1、format是必须的
2、不会自动换行,需显式给定行分隔符
3、format中需要分别为后面的每个item指定一个格式符
格式符:都以%开头,后跟一个字符
%c:显示字符的ASCII码
%d,%i:显示十进制整数
%e,%E:科学计数法显示数值
%f:显示为浮点数
%s:字符串
%g,%G:以科学计数法格式或浮点数格式显示数值
%u:无符号的整数
%%:显示%自身
修饰符:
#[.#]:第一个#显示宽度,第二个#显示精度例如:%3.2s
-:表示左对齐 %-3d表示左对齐
+:显示数值符号
四、操作符:
算数操作符:
+,-,*,/,%
-x:负值
+x:转换为数值
字符串操作:字符串连接
赋值操作符:
=,+=,-=,*=,/=,%=,^=,++,--
比较操作符:
>,<,>=,<=, ==, !=
模式匹配符:~
逻辑操作符:&& ||
条件表达式:?:
函数调用:function_name(argu1,argu2,….)
例:awk -F:‘{$3>=500?usertype="common user":usertype="sysuser oradmin";printf "%20s:%-s\n",$1,usertype}‘ /etc/passwd
五、PATTERN
1、/regularexpression/: 仅处理被/regular expression/匹配到的行
2、relationalexpression: 关系表达式,有真假之分,一般来讲,非0或非空字符串则为真,否则为假
3、line ranges:行范围,类似sed或vim的地址定界法
4、GEGIN/END:仅在awk运行程序之前或之后执行一次
5、empty:空模式,匹配任意行
六、常用的acion
1、expression
2、control statements
3、compound statements
4、input statements
5、output statements
七、控制语句
if (condition)statement [ else statement ]
while(condition) statement
do statementwhile (condition)
for (expr1;expr2; expr3) statement
for (var in array) statement
break
continue
delete array[index]
delete array
exit [ expression ]
{ statements }
7.1 if-else
语法:if (condition)statement [ else statement ]
if (condition){ statements; } [ else { statements; }]
# awk -F: ‘{if ($3>=500) print $1," is a common user."}‘ /etc/passwd
# awk -F: ‘{if($3>=500) {print $1," is a common user."} else {print $1," isa system user or admin."}}‘ /etc/passwd
# awk ‘{if(NF>6) print NF, $0 }‘ /etc/inittab
用法:对awk取得的整行或行中的字段做条件判断;
7.2 while循环
语法:while(condition) statement
while(condition) { statements }
条件为真时进行循环,直到为假退出;
用法:通常用于在当前行的各字段间进行循环;
# awk ‘{i=1;while(i<=NF){printf"%20s:%d\n",$i,length($i); i++}}‘ /etc/inittab
# awk ‘{i=1;while(i<=NF){if(length($i)>5) {printf "%20s:%d\n",$i,length($i);} i++}}‘/etc/inittab
7.3 do-while循环
语法:do statement while(condition)
do { do-while-body } while(condition)
意义:至少执行一次循环体;
7.4 for循环
语法:for(expr1; expr2; expr3) statement
for (expr1;expr2; expr3) { statements }
for (varaiable assignment; condition; iteration process) { for-body}
# awk ‘{for(i=1;i<=NF;i++) {printf "%s:%d\n", $i,length($i)}}‘ /etc/inittab
for循环在awk中有一个专用于遍历数组元素:
语法:for (var in array){ for-body }
7.5 switch
语法:switch(expression) {case VALUE or /REGEXP/: statement; ...; default: statementN}
7.6 break and continue
break [n]: 退出当前循环
continue:提前结束本轮循环,直接进入下轮循环
7.7 next
提前结束对本行的处理而进入下一行的处理
# awk -F: ‘{if($3%2!=0)next;print $1,$3}‘ /etc/passwd
八、Array
关联数组:array[index-expression]
index-expression:
可以使用任意字符串;
如果某数组元素事先不存在,在引用时,awk会自动创建此元素并将其值初始化为空串;
因此,若要判断数组是否存在某元素,要使用“index in array”进行;
a[mon]="Monday"
print a[mon]
要遍历数组中的每个元素,使用:for(var in array) { for body }
注意:var会遍历array的每一个索引,print array[var]
例子:统计每一行中各单词分别出现的次数
# awk ‘{for(i=1;i<=NF;i++){count[$i]++}}END{for(j in count) {print j,count[j]}}‘ awk.txt
# ss -tan | awk‘!/^State/{state[$1]++}END{for (i in state) {print i,state[i]}}‘
# netstat -tan | awk‘/^tcp/{state[$NF]++}END{for(i in state){print i,state[i]}}‘
例如:统计httpd访问日志中,每个IP出现的次数;
# awk ‘{ip[$1]++}END{for(i in ip){printi,ip[i]}}‘ /var/log/httpd/access_log
九、函数
9.1 内置函数
数值处理:
rand():返回0和1之间一个随机数;
字符串处理:
length([s]):返回指定字符串的长度
sub(r, s [,t]):以r所表示的模式来查找t字符串中的匹配,将其第一次出现替换同s所表示的字符串;
sub(ab,AB,$0)
gsub(r, s [,t]):以r所表示的模式来查找t字符串中的匹配,将其所有的出现均替换同s所表示的字符串;
split(s, a [,r]): 以r为分隔符切割字符串s,并将切割的结果保存至a表示数组中;
# netstat -tan| awk ‘/^tcp/{len=split($5,client,":");ip[client[len-1]]++}END{for(iin ip){print i,ip[i]}}‘
substr(s, i [,n]):从s表示的字符串中取子串,从i开始,取n个字符;
时间类的函数:
systime(): 取时间戳;
位运算函数:
and(v1,va2):
9.2 自定义函数
functionf_name(p,q)
{
...
}