awk [-F] '{pattern + action}' {filenames} 或者 awk -F 'pattern {action}' filenames
-F 域分隔符是可选的,因为awk使用空格作为缺省的域分隔符,因此如果要浏览域间有空格的文本,不必指定这个选项
一. awk内置变量
ARGC 命令行参数个数 ARGV 命令行参数排列 ENVIRON 支持队列中系统环境变量的使用 FILENAME awk浏览的文件名 FNR 浏览文件的记录数 FS 设置输入域分隔符,等价于命令行 -F选项 NF 浏览记录的域的个数 NR 已读的记录数 OFS 输出域分隔符 ORS 输出记录分隔符 RS 控制记录分隔符
二. awk内置函数
gsub(r,s) | 在整个$0中用s代替r |
gsub(r,s,t) | 在整个t中用s替代r |
index(s,t) | 返回s中字符串t的第一位置 |
length(s) | 返回s长度 |
match(s,r) | 测试s是否包含匹配r的字符串 |
split(s,a,fs) | 在fs上将s分成序列a |
sprint(fmt,exp) | 返回经fmt格式化后的exp |
sub(r,s) | 用$0中最左边最长的子串代替s |
substr(s,p) | 返回字符串s中从p开始的后缀部分 |
substr(s,p,n) | 返回字符串s中从p开始长度为n的后缀部分 |
gsub函数有点类似于sed查找和替换。它允许替换一个字符串或字符为另一个字符串或字符,并以正则表达式的形式执行
sprint函数类似于printf函数,返回基本输出格式fmt的结果字符串exp。
三. 算术及逻辑运算符,条件运算符
+、-、*、/、% ++、--、+=、-=、=+、=- log、sqr、cos、sin等等
!(非)、&&;(与)、||(或)和括号()进行多重判断
==(等于)、!=(不等于)、>(大于)、>=(大于等于)、<=(小于等于)~(匹配于)和!~(不匹配于)判断等等
四. 流程控制
1. BEGIN{} END{}
在awk 中两个特别的表达式,BEGIN和END,这两者都可用于pattern中(参考前面的awk语法)
提供BEGIN和END的作用是给程序赋予初始状态和在程序结束之后执行一些扫尾的工作。
任何在BEGIN之后列出的操作(在{}内)将在awk开始扫描输入之前执行,
而END之后列出的操作将在扫描完全部的输入之后执行。
因此,通常使用BEGIN来显示变量和预置(初始化)变量,使用END来输出最终结果。
2. if(表达式){语句1}else{语句2}
嵌套时例如:
if(表达式1){
if(表达式2)语句1else语句2} 语句3
else {
if(表达式3)语句4 else 语句5
} 语句6
3. while(表达式) 语句 与 do{语句}while(条件判断语句)
4.. for(初始表达式;终止条件;步长表达式){语句}
在awk 的 while、do-while和for语句中允许使用break,continue语句来控制流程走向,也允许使用exit这样的语句来退出。
break 中断当前正在执行的循环并跳到循环外执行下一条语句。
continue从当前位置跳到循环开始处执行。
对于exit的执行有两种情况:当exit语句不在 END中时,任何操作中的exit命令表现得如同到了文件尾,所有模式或操作执行将停止,END模式中的操作被执行。而出现在END中的exit将导致程序终止。
五. 函数
function 函数名(参数表){
}
执行完全部语句或者在函数体中执行return
六. 输入输出.
1.next 读取下一条记录
2.getline 简单地读取一条记录
七.栗子,作者写的low逼版,无参考价值的命令
1. 通过一句很low的日志, 统计计算上个月某个功能请求次数和平均耗时.
grep -r 请求总耗时 2017_08_*|grep MerInfoQueryBusiness |awk -F ':' '{ print $2}' |awk -F 'ms' '{a[NR]=$1}END{for(i=1;i<=NR;i++){ b+=a[i] } print b/i,i} '
1>首先通过grep 搜索命令递归获取该路径下所有8月份日志中中有关请求总耗时的单条信息.
grep -r 请求总耗时 2017_08_*
2> 接着通过管道命令 | 将第一个指令的结果作为第二个指令的输入参数. 在第二个指令中 搜索某个功能相关的数据.
|grep MerInfoQueryBusiness
3>继续使用管道 使用awk进行分割的操作,通过 : 分隔符获取和耗时相关的数据.
|awk -F ':' '{ print $2}'
4> |awk -F 'ms' '{a[NR]=$1}END{for(i=1;i<=NR;i++){ b+=a[i] } print b/i,i} '
将结果继续进行处理. 首先将单位符号和数据进行分离,这样操作之后,我们就可以对数据进行统计操作.
'{a[NR]=$1}END{for(i=1;i<=NR;i++){ b+=a[i] } print b/i,i} '
首先, 这边使用到了内置变量 NR [已读的记录数] 创建一个数组,将分离后每一行记录的数值放置在已读记录对应的数组 a[] 中.
然后使用 END{} 表达式 在读取完所有的记录存储在数组后进行后续的操作.
使用for循环, 遍历记录数组, 将时间累加 存储在变量b中.
最后输出平均耗时=总时长/请求次数 与 请求次数
2. 通过一个还算可以的简要日志, 按照失败原因, 统计所有失败请求的次数, 并且按照数量排序.
cat mpsp_daily.log |awk -F ',' '{ if ($4 != 0000 ) print $3, $4 , $16}' |awk '{a[$0]++!b[$0]++} END{for (i in a) print a[i] ,",", i }' |sort -rn -k 1 -t ","
首先读取到日志文件全文. cat mpsp_daily.log
接着将之前的数据作为参数传入, 通过字段分隔符 ' , ' 将不同的数据做区分 判断接口请求失败, 过滤出我们需要的数据 |awk -F ',' '{ if ($4 != 0000 ) print $3, $4 , $16}'
然后我们将拿到的失败数据进行统计. 每行数据都 进行了 a[$0]++!b[$0]++操作.
a[$0]++ 是无条件将整行数据进行累加.
!b[$0] 当相同的行第一次读入时,行乎略 就是想只保留重复记录中第一次出现的记录
在END{} 表达式 中对 数组a进行了遍历.
最后使用sort 功能对结果进行了排序. 中间对,进行分离 使用次数进行排序
-k KeyDefinition 指定排序关键字
-t ',' 指定 , 为单一的字段分隔符。
-r 以相反的顺序来排序。
-n 依照数值的大小排序。
日志啥的以后再补.. 第二个写的也有点问题....
-----------------------------------------------------------------------------------------------------------------------------------
awk分隔后,base64解密并且进行bcd转ascii
awk -F '","' '{cmd=sprintf("echo -n %s|base64 -d|xxd -ps", $1); system(cmd); print "";}'
按照字符位置进行剪切
cut -c21-24
过滤空白行
grep -v '^\s*$'