awk '条件类型1{动作1} 条件类型2{动作2} ...' filename

1.awk主要是处理每一行的字段内的数据,而默认的字段的分隔符为空格或【tab】
2.以$0代表整行,$1代表第一个字段,$2 代表第二个字段,以此类推。
3.与shell不同,awk中变量不需要加$(除非是$后跟数字代表各字段或整行)
4.awk后续的所有动作是以单引号括住的,awk的格式内容如果想要print打印时,文字(包括printf格式中)都需要用双引号来定义
5.在{}内如果有多个命令辅助时,可利用分号“;”间隔,或者直接以回车分隔,格式化输出时记得加“\n”

一、条件类型(pattern):
1、Regexp: 正则表达式,格式为/regular expression/
2、expresssion: 表达式,其值非0或为非空字符时满足条件,如:$1 ~ /foo/ 或 $1 == "xinlulicheng",用运算符~(匹配)和!~(不匹配)。
3、Ranges: 指定的匹配范围,格式为pat1,pat2
4、BEGIN/END:特殊模式,仅在awk命令执行前运行一次或结束前运行一次
5、Empty(空模式):匹配任意输入行;

二、内置变量:
FS:目前的分隔字符,默认是空格或【tab】 (field-separator)   -F 后面直接(或用引号括起)来指定分隔符,或后面跟[]指定多个分割符。
OFS: Output Filed Separator
RS: Record separator,输入文本信息所使用的换行符;
ORS:Output Row Separator:
NF:每一行($0)拥有的字段总数 (Number of Field) $NF表示每一行最后一个字段。
NR:目前awk所处理的是“第几行”数据  (NR可以理解为Number of Record的缩写)
FNR:在awk处理多个输入文件的时候,在处理完第一个文件后,NR并不会从1开始,而是继续累加,因此就出现了FNR,每当处理一个新文件的时候,FNR就从1开始计数,FNR可以理解为File Number of Record。
FILENAME: 文件名

三、自定义变量两种方法:
awk 'BEGIN{var="variable testing";print var}'
awk -v var="variable testing" 'BEGIN{print var}'

四、控制语句
1 if-else
语法:if (condition) {then-body} else {[ else-body ]}
例子:
awk -F: '{if ($1=="root") print $1, "Admin"; else print $1, "Common User"}' /etc/passwd
awk -F: '{if ($1=="root") printf "%-15s: %s\n", $1,"Admin"; else printf "%-15s: %s\n", $1, "Common User"}' /etc/passwd
awk -F: -v sum=0 '{if ($3>=500) sum++}END{print sum}' /etc/passwd

2 while
语法: while (condition){statement1; statment2; ...}
awk -F: '{i=1;while (i<=3) {print $i;i++}}' /etc/passwd
awk -F: '{i=1;while (i<=NF) { if (length($i)>=4) {print $i}; i++ }}' /etc/passwd

3 do-while
语法: do {statement1, statement2, ...} while (condition)
awk -F: '{i=1;do {print $i;i++}while(i<=3)}' /etc/passwd

4 for
语法: for ( variable assignment; condition; iteration process) { statement1, statement2, ...}
awk -F: '{for(i=1;i<=3;i++) print $i}' /etc/passwd
awk -F: '{for(i=1;i<=NF;i++) { if (length($i)>=4) {print $i}}}' /etc/passwd

for循环还可以用来遍历数组元素:
语法: for (i in array) {statement1, statement2, ...}
awk -F: '$NF!~/^$/{BASH[$NF]++}END{for(A in BASH){printf "%15s:%i\n",A,BASH[A]}}' /etc/passwd

5 case
语法:switch (expression) { case VALUE or /REGEXP/: statement1, statement2,... default: statement1, ...}

6 break 和 continue
常用于循环或case语句中

7 next
提前结束对本行文本的处理,并接着处理下一行;例如,下面的命令将显示其ID号为奇数的用户:
# awk -F: '{if($3%2==0) next;print $1,$3}' /etc/passwd

五、数组
array[index-expression]
从关系数组中删除数组索引需要使用delete命令。使用格式为:delete  array[index]


统计apache日志文件中IP地址的访问量:
awk '{counts[$1]++}; END {for(ip in counts) print counts[ip], ip}' /var/log/httpd/access_log

netstat -ant | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
每出现一被/^tcp/模式匹配到的行,数组S[$NF]就加1,NF为当前匹配到的行的最后一个字段,此处用其值做为数组S的元素索引;


六、awk的内置函数

split(string, array [, fieldsep [, seps ] ])
功能:将string表示的字符串以fieldsep为分隔符进行分隔,并将分隔后的结果保存至array为名的数组中;数组下标为从0开始的序列;

netstat -ant | awk '/:80\>/{split($5,clients,":");IP[clients[1]]++}END{for(i in IP){print IP[i],i}}' | sort -rn | head -50

length([string])
功能:返回string字符串中字符的个数;


substr(string, start [, length])
功能:取string字符串中的子串,从start开始,取length个;start从1开始计数;

system(command)
功能:执行系统command并将结果返回至awk命令

systime()
功能:取系统当前时间

tolower(s)
功能:将s中的所有字母转为小写

toupper(s)
功能:将s中的所有字母转为大写

七、用户自定义函数

自定义函数使用function关键字。格式如下:

function F_NAME([variable])
{
    statements
}

函数还可以使用return语句返回值,格式为“return value”。

有任何疑问请点击留言: 留言板
本文发布于http://wiki.too2.net,转载请联系本人。