awk是文本分析工具,适合对数据进行分析生成报告。awk是逐行的读入,默认以空格为默认分隔符,也可以使用-F参数指定分隔符,然后对切开的部分进行各种分析处理。
awk有三个不同的版本:awk nawk和gawk,一般我们使用的是gawk,是gnu版本。
[root@nfs01 ~]# ls -al /usr/bin/awk lrwxrwxrwx. 1 root root 4 Dec 17 11:42 /usr/bin/awk -> gawk
awk命令格式:
awk [-F|-f|-v] 'BEGIN{}//{command1;command2}END{}' file
-F 指定分隔符(常用),-f调用脚本,-v定义变量var=value
' ' 引用代码块
BEGIN 初始化代码块,在对每一行进行处理之前,初始化代码块,主要是引用全局变量,设置FS分隔符
// 匹配代码块,可以使字符串或者正则表达式
{ } 命令代码块,包换一条或者多条命令
; 多条命令使用分隔符
END 结尾代码块,在对每一行进行处理之后,再执行的代码块,主要是进行最终计算或输出结尾摘要信息
特殊要点:
$0 表示真个当前行
$1 每行第一个字段
NF 字段数量变量
NR 每行记录号,多文件记录递增,行号
FNR 与NR类似,不过多文件记录不递增,每个文件都是从1开始
制表符
换行符
FS BEGIN时定义分隔符
RS 输入的记录分隔符,默认为换行符(即文本按一行一行输入)
~ 匹配,与==相比不是精确比较
!~ 不匹配,不精确比较
== 等于,必须全部相等,精确比较
!= 不等于,精确比较
&& 逻辑与
|| 逻辑或
+ 匹配时表示1个或者1个以上
/[0-9][0-9]+/ 两个或两个以上的数字
/[0-9][0-9]-/ 一个或一个以上的数字
OFS 输出字段分隔符,默认也是空格,可以改为制表符等
ORS 输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕
-F'[:#/]' 定义三个分隔符
print & $0
print是awk打印指定内容的主要命令
awk '{print " "}' /etc/paaawd 输出相同数量的空行
awk '{print "a"}' /etc/passwd 输出n行a
awk -F: '{print $1}' /etc/passwd 指定分隔符为:,输出每一行第一个字段
awk -F: '{print $1,$2,$3}' OFS=" " /etc/passwd 输出字段123,比制表符作为默认分隔符
-f 指定脚本文件
awk -f script.awk file
BEGIN{
FS=":"
}
{print $1}
-F指定分隔符
awk -F":" '{print $1,$3}' /etc/passwd 指定每行以:为分隔符,打印第一个和第三个字段
awk -F: 'NR==5||NR==6{print}' /etc/passwd 显示第五行和第六行
awk -F: 'NF>2{print $0}' /etc/passwd 显示每行字段大于2的行
route -n|awk 'NR!=1{print}' 不显示第一行
这个指定分隔符比较简单,就不在赘述
//匹配代码块
//纯字符匹配 !//纯字符不匹配 ~//字段值匹配 !~// 字段值不匹配 ~/a1|a2/字段匹配a1或a2
awk '/root/' /etc/passwd
awk -F: '/mail/,/root/{print}' /etc/passwd
awk '/[2][7][7]*/{print $0}' /etc/passwd 匹配包含277开头的行
IF语句
必须用在{}中,且比较内容用()括起来
awk -F: '{if ($1~/mail/) print $1} ' /etc/passwd
条件表达式
== != > >=
awk -F: '$3>1000{print $1}' /etc/passwd 显示uid大于1000的用户名
逻辑运算符
&& ||
awk -F: '{if($1~/shutdown/&&$3>8) print}' /etc/passwd
数值运算
awk -F: '$3 > 100' /etc/passwd
awk -F: '/mysql/{print $2/1024}' /proc/meminfo
输出分隔符OFS
aws '$6 ~ /FIN/ || NR==1 {print NR,$4,$5,$6}' OFS=" " netstat.txt
输出处理结果到文件
route -n |awk 'NR!=1{print > "./fs"}'
route -n |awk 'NR!=1{print}' > ./fs
格式化输出
netstat -anp|awk '$6=="LISTEN" || NR==1 {printf "%-10s %-10s %-10s ",$1,$2,$3}'
IF语句
awk -F: '{if($3>100) print "large"; else print "small"}' /etc/passwd
while语句
数组
netstat -anp|awk 'NR!=1{a[$6]++}END{for (i in a)print i," ",a[i]}'
学习来源:http://blog.chinaunix.net/uid-23302288-id-3785105.html