awk注意执行语句为单引号
1、awk为文本处理语言、命名于三位创始人
awk对文本进行匹配,然后进行逐行操作
2、awk分为模式和动作
awk pattern action
如果没有模式,动作应用到全部行
awk [ops] 'pattern{action}' filename arg1 arg2
3、模式6种
1)模式类型:
2)/正则表达式/
3)关系运算符
4)模式匹配表达式 ~ !~
5)模式
6)BEGIN 第一条记录前发生的动作
7)END 最后一条记录后发生的动作
4、动作5种
动作包括:
1)变量
2)数组
3)输出
4)内置函数
5)流程控制
5、内置环境变量
1)$n 当前记录的第n个字段 字段间由FS分割
2)$0 完整的输入记录
3)ARGC 命令行参数个数
4)ARGV 命令行参数数组
5)FS 字段分割符 默认空格
6)NF 当前记录的字段数
7)NR 当前记录数
8)FS 域分隔符
9)RS 记录分隔符
10)OFS 输出域分隔符
11)ORS 输出记录分隔符
6、awk运算符
1)赋值运算符 += = -= /= *= ^= **=
2)条件表达式 :
3)逻辑运算符 && ||
4)匹配正则表达式与不匹配 ~ ~!
5)关系运算符 > >= < <= != ==
6)字段引用 $
7)数组成员 in
7、记录
awk以换行符区分行
每一行为一个记录
$0代表当前整个行记录
NR代表当前记录数
8、域(字段)
默认空格或者tab制表符作为分割,分割的每一部分叫做域
$n 为对第n个域的记录
指定域分隔符采用 -F 来替换FS默认的空格 -F: 以冒号分割
-F'[:\t]' 以冒号、制表符、空格分隔
9、变量
awk中定义变量可直接使用
域变量可赋值和修改
参数变量可直接使用
10、BEGIN
awk 'BEGIN{}{action}' begin之后紧跟动作,begin动作要在action之前。
通常用于改变既定内建变量,设定全局变量
11、END
awk '{action}END{}' end用于所有记录处理完成之后
12、管道和重定向
同shell语法
13、条件判断
if (){
}
if (){
}else{
}
if(){
}else if(){
}
14、条件循环
while(){
}
15、遍历循环
for(;;){
}
for(a in arr){
}
此处a为下标
16、数组
定义,下标可以是数值或者字符,下标从1开始
arr[1]=$1
arr[2]=$1
取值
arr[1]
arr[2]
awk会将数组下标变为字符串
一般将表现形式为字符串的下标的数组称为关联数组
17、字符串函数
1)替换 sub
sub(/正则/,"abc") 如果不指定目标字符串正则,则默认整个记录替换
2)查找 index
index("mytest","test") 查找test在mytest中的位置
默认从1开始
3)长度 length
length 默认整个记录
length("abc") 长度为3
4)截取 substr
substr(str,start,end)
5)正则查找 match
match(str,正则) 无则返回0
6)分割 split
split(str,arr,seperator) 分割到arr数组
7)大小写
toupper(str)
tolower(str)
18、systime()时间函数
strftime 格式化时间函数
strftime("%m%y",systime())
19、输出
print
等同于 print $0
练习
abc 200 1 james
def 2 301 white
ghi 3 302 alian
404 jkl 4 li
mno 5 500 wan
pqr 507 6:ming
1)
awk '{print $1}' t1
awk '{print $0}' t1
awk '{print}' t1
awk '{print "abc"}' t1
2)
awk -F'[ :]' '{print $4}' t1
根据空格或冒号分割
3)
awk -F'[ :]' '$2 ~ /[0-9]+/{print}' t1
字符串匹配
采用 == "abc"
或者 ~ 正则
4)
awk -F'[ :]' '{if($2 ~ /[0-9]+/)print $1}' t1
5)
awk --posix -F'[ :]' '{if($2 ~ /[0-9]+/){if($3 ~ /[0-9]{3}/){print $3}else{print "no 3 len"}}}' t1
awk中正则表达式如果用到了大括号{}就要使用--posix
此处限定$3匹配三个数字
6)
FS="foo[0-9]{3}"
设置分隔符为foo三个数字
7)
awk '{print NF}' t1
awk '{print NR}' t1
8)
12345foo123abc
amcfoo123654
awk 'BEGIN{FS="foo[0-9]{3}"}{print $1 " " $2}' t2
设置分隔符为foo三个数字
james
29
yanj
white
28
shahe
alian
29
peking
awk 'BEGIN{FS="\n";RS=""}{print $1 $2 $3}' t3
设置分隔符为回车,记录分隔符为空白行。则每一行打印出文件的三行
9)
awk 'BEGIN{FS="\n";RS="";OFS=", ";ORS=";"}{print $1 $2 $3}END{print "\n"}' t3
10)
awk '{i;while(i <= NF){print $i;i++}}' t3
11)
awk 'BEGIN{arr[1]="my";arr[2]="heart"}{for(inde in arr){print inde}}'
awk 'BEGIN{arr[1]="my";arr[2]="heart"}{for(inde in arr){print arr[inde]}}'
awk 'BEGIN{arr["200"]="my";arr["301"]="heart"}{for(inde in arr){print inde}}'
awk 'BEGIN{arr["a"]="my";arr["b"]="heart"}{for(inde in arr){print arr[inde]}}'
12)
格式化printf
awk '{printf("%s age is %i ","zhangqiang",29)}'
13)
awk 's="mys";print length(s)'
awk 'BEGIN{arr[1]=2;arr[2]=3}{print length(arr)}'
length用于求数组或者字符串长度
14)
awk '{print index("my world is here","is")}'
index 定位字符串位置
15)
awk '{print toupper("my")}'
字符串变大写
16)
awk '{print tolower("MY")}'
字符串变小写
17)
awk '{print substr("here",1,2)}'
2为截取长度
18)
awk '{print substr("i e y",/e/)}'
通过使用循环显示所有的匹配
会将位置和长度存于RSTART、RLENGTH中
19)
awk '{s="you me and we";sub(/me/,"test",s)};print s}'
必须将字符串定义成变量,否则无法打印查看
20)
总结:统计文档中特定字符出现个数。如http状态码.
本例子没有统计一个文件中的多个状态码情况
awk --posix '{if(match($0,/[0-9]{3}/) != 0){st=substr($0,RSTART,RLENGTH);as[st]=as[st]+1}}END{for(a in as){print as[a]}}' t1
21)
打印出指定信息及信息的上三行
awk 'BEGIN{inde=0}{if(NR % 3 == 0){print arr[1]=$0; arrIndex[1]=NR};if( NR % 3 == 1){arr[2]=$0; arrIndex[2]=NR};if(NR % 3 == 2){arr[3]=$0; arrIndex[3]=NR};if(index($0,"Exception")>0){if(arrIndex[1] != NR){print arrIndex[1] " " arr[1]};if(arrIndex[2] != NR){print
arrIndex[2] " " arr[2]};if(arrIndex[3] != NR){inde = NR ;print
arrIndex[3] " " arr[3]}; print NR " 异常 "
$0 "\n\n";};print inde "发现异常序号";if(NR > inde && NR < inde+3){print NR " " $0}}' catalina.out
22)统计文件总行数 awk 'END{print NR}'
sed -n '/Exception/{=;p}' localhost.2016-05-15.log >> /data/
loganalyze_exception2
.txt
22)访问日志localhost_access中请求处理时间大于200ms的记录
{
if($NF > 200){
print $0;
}
}
23)统计文件中出现某词的个数
以请求download计算
awk 'BEGIN{count=0}/
download/{count = count + 1}END{print count}' localhost_access_log.2016-05-18.txt