先在此至敬朱双印老师,博客写得很详细:http://www.zsythink.net/archives/tag/awk/ 这是朱双印老师关于awk博客的链接,强力推荐给大家
AWK一般在网上说是一种处理文本文件的语言,也是一个强大的文本分析工具。
虽然我也认同这种说法,但是在此我的认知是:
awk是逐行处理文本文件的语言/分析工具
从上面朱老师的图中可以看到,$0表示整行,其它的就是以分隔符进行划分的了
变量名称
|
代表意义
|
NF
|
每一行 ($0) 拥有的栏位总数
|
NR
|
目前 awk 所处理的是『第几行』数据
|
FS
|
目前的分隔字节,默认是空白键
|
命令参数格式
#awk '条件类型1{动作1} 条件类型2{动作2} ...' filename
-F 指定输入分隔符【此处其实是可以使用多个分隔符进行分隔的,例:< awk -F '[-|]' '{print $3}' FileName>】
#cat /usr/local/mail/app/log/authenticator.log|grep 'none'|awk -F '[<>{}]' '{print $2,$4}'
-v 【options】的一种,用于设置变量的值
-v OFS="+++" 【使用变量要配合-v选项】OFS可以设定awk的输出分隔符
ARGC 命令行参数个数
ARGV 命令行参数排列
ENVIRON 支持队列中系统环境变量的使用
FILENAME awk浏览的文件名 【显示当前处理的文件名】
FNR 浏览文件的记录数【如同时处理多个文件,会分别计算行数】
FS 设置输入域分隔符,等价于命令行 -F选项
NF 浏览记录的域的个数
NR 已读的记录数
ORS 输出记录分隔符【真正的输出行分隔符】
RS 控制记录分隔符 【默认是以换行作为行分隔,比如需要定义空格作为行分隔】
#BEGIN表示在开始逐行处理文件之前指定的动作
#END表示在结束逐行处理文件之后指定的动作
例:
#awk 'BEGIN{print "aaaa","bbbb"} {print $1,$2} END{print "cccc","dddd"}' test
分隔符: -F 进行定义
#awk -F# '{print $1,$2}' test
#awk -F “#” '{print $1,$2}' test
#awk -v FS='#' '{print $1,$2}' test
awk支持的关系运算符
关系运算符 含义 用法示例
< 小于 x<y
<= 小于等于 x<=y
== 等于 x==y
!= 不等于 x!=y
>= 大于等于 x>=y
> 大于 x>y
~ 与对应 与此同时匹配则为真 x ~ /正则/
!~ 与对应的正则不匹配则为真 x !~ /正则/
awk 模式
1、空模式
2、关系运算模式
3、BEGIN/END模式
4、正则模式
5、行范围模式
awk正则格式
awk使用的正则用法属于“扩展正则表达式”,当使用{x,y}这咎次数匹配的正则表达式时,需要配合--posix选项或者--re-interval选项
#awk '/正则表达式/{}' filename
例:
#awk -F ":" 'BEGIN{printf "%-10s%-10s\n","用户名","用户ID"} /^zsy/{printf "%-10s\t%-10s\n",$1,$3}' /etc/passwd
#awk '/\/bin\/bash$/{print $0}' /etc/passwd 《注意转义字符》
#awk --posix '/he{2,3}y/{print $0}' test3 《注意需要使用--posix》
#awk --re-interval '/he{2,3}y/{print $0}' test3 《或者使用--re-interval》
awk行范围模式
例:搜索某两个内容之间出现的行
#awk '/正则1/,/正则2/{动作}' /some/file
#awk 'NR>=3 && NR<=6 {print $0}' filename
例:awk提取IP地址的一个示例
#awk --posix '$2~/192\.168\.[0-9]{1,3}\.[0-9]\.{1,3}/{print $1,$2}' filename
awk中使用IF
#awk -F ":" '{if($3<500){print $1,"系统用户"} else{print $1,"普通用户"} }' /etc/passwd
#awk 'BEGIN{ for(i=0;i<6;i++){if(i=3){continue}; print i}}'
NEXT可以促使AWK不对当前行执行对应的动作,而直接处理下一行
#awk '{ if(NR==2){ next }; print $0}' test9
AWK数组
#awk 'BEGIN{ a[1]="a1";a[2]="a2"; for(i=1;i<=2;i++){print i,a[i]} }'
#awk 'BEGIN{ a[1]="a1";a[2]="a2"; for(i in a){print i,a[i]} }'
统计某个IP出现的次数
#awk '{ count[$i]++} END{ for(i in count){print i,count[i]} }' test10
算数函数
rand函数、srand函数、int函数
rand函数生成随机数,但是是固定的,需要结合srand
随机一个数
#awk 'BEGIN{print rand()}'
#awk 'BEGIN{srand(); print rand()}'
随机一个数,并且乘以100
#awk 'BEGIN{srand(); print 100*rand()}'
生成一个随机数,乘以100,并且截取整数部分
#awk 'BEGIN{srand(); print int(100*rand())}'
字符串函数
gsub
例:将第一列中的小写字母“l"都替换成大写字母”L",【$1表示第一列,如果删除$1,则表示所有的均替换】
#awk '{gsub("l","L",$1);print $0}' test11
#awk '{gsub("[a-z]","6",$1);print $0}' test11
sub 表示替换指定范围内第一次匹配到的符合条件的字符,使用方法与gsub一样,不举例
length 获取指定字符串的长度,如果不传入任何字符,则以$0作为参数
#awk '{for(i=1;i<=NF;i++){print $i,length($i)}}' test11
index获取指定字符串位于整个字符串中的位置,示例:<如果不存在则返回0>
#awk '{print index($0,"Lee")}' test11
split 将指定的字符串按照指定的分割符切割,将切割后的每一段赋值到数组的元素中,从而动态创建数组,示例如下:
并且split函数的返回值的内容是数组的长度:
split分割后的数组的下标是从1开始
#awk -v ts="大娃;二娃;三娃" ' BEGIN{split(ts,huluwa,";"); for(i in huluwa){print huluwa[i]} } '
#awk -v ts="大娃;二娃;三娃" 'BEGIN{ print split(ts,huluwa,";" )}'
#awk -v ts="qq te ab th" 'BEGIN{ arrlen=split(ts,arr," "); for(i=1;i<=arrlen;i++){print i,arr[i]} }'
asort根据元素的值进行排序
#awk 'BEGIN{ t["a"]=66;t["b"]=3; asort(t); for(i in t){print i,t[i]}}'
#awk 'BEGIN{ t["a"]=66;t["b"]=3; asort(t); for(i in t){print i,t[i]} }'
#awk 'BEGIN{ t["a"]=66;t["b"]=3; asort(t,newt); for(i in newt){print i,newt[i]} }'
三元运算
普通示例:获取UID小于500的用户,进行判断是否是普通用户
#awk -F ":" '{if($3<500){usertype="系统用户"}else{usertype="普通用户"};print $1,usertype}' /etc/passwd
三元运算的写法
#awk -F ":" '{usertype=$3<500?"系统用户":"普通用户";print $1,usertype}' /etc/passwd
#awk -F ":" '{$3<500?a++:b++} END{print a,b}' /etc/passwd
打印奇偶行<i初始值为0,再利用!进行取反>
打印奇数行
#awk 'i=!i' test2
打印偶数行
#awk '!(i=!i)' test2