这篇文章主要讲解了“awk使用示例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“awk使用示例分析”吧! awk是一个强大的文本分析工具。 awk其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。实际上 awk 的确拥有自己的语言: awk 程序设计语言 , 三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。 BEGIN 关键字会执行一次指定的脚本段
END 关键字定义的脚本段,在所有操作完成之后
处理数据的脚本段在第二个程序中定义 记录 默认指的是每行,因为记录分隔符(RS)是换行符 域 默认指的是每个单词,因为域分隔符(FS)是空格 awk 通过内建变量 ARGC ( 参数计数 ) 与 ARGV ( 参数向量,或参数值 ) ,让命令行参数可用。 cat showargs.awk BEGIN { print "ARGC= ", for 0; k<ARGC; k++) { print "ARGV["k"]=["ARGV[k]"]" } } awk -f showargs.awk mi_info # ARGC= 2# ARGV[0]=[awk] # ARGV[1]=[mi_info] ## 求和 awk '{sum+=$NF} END {print "Sum = ", sum}' mi_info # Sum = 21693
## 求平均 awk '{sum+=$NF} END {print "Average = ", sum/NR}' mi_info # Average = 3099
## 求最大值 awk 'BEGIN {max = 0} {if ($NF>max) max=$NF fi} END {print "Max=", max}' mi_info # Max= 3999
## 求最小值(min的初始值设置一个超大数即可) awk 'BEGIN {min = 1999999} {if ($NF<min) min=$NF fi} END {print "Min=", min}' mi_info # Min= 2499
# 求访问次数的Top 10 Resource,可以根据此进行优化 cat logs/`date +%u`.log | grep -v '172.16' |grep -v '127.0.0.1' \ | awk '{ if(index($1,"219.141.246")!=0) print $2; else print $1 }' \ | sort | uniq -c | sort -n | tail -n 10
# awk的范围模式也是封闭范围。 # 在所有记录中他们会顺序进行多次匹配,第一次匹配完后还可以进行下面接下来的第二次、第三次可能的匹配范围。 # 如果开头匹配到了,但是没有结尾的话,会把整个文件记录的末尾当作是这次匹配的结尾作为范围 awk '/mi6/,/note/ {print NR, $1, $NF}' mi_info # 1 mi6-1 2499 # 2 mi6-2 2899 # 3 minote3-1 2499 # 忽略大小写 awk '{IGNORECASE=1}; $1~"MI" {print NR,$0}' mi_info # "所有信息" # 每 5 行合并为 1 行 BEGIN { a = 0; s = ""; } { a += 1; s = s" | "$0 if (a % 5 == 0) { print s; s = ""; } } END { print s } awk 'BEGIN{a="100"; b="10test10"; print (a+b+0);}' # 110 # 只需要将变量通过 "+" 连接运算。自动强制将字符串转为整型。 # 非数字变成 0,发现第一个非数字字符,后面自动忽略。 awk 'BEGIN{a=100;b=100;c=(a""b);print c}' # 100100 # 只需要将变量与 "" 符号连接起来运算即可。 awk 'BEGIN{a="a";b="b";c=(a+b);print c}' # 0 # 字符串连接操作通"二","+"号操作符。模式强制将左右2边的值转为 数字类型。然后进行操作。数组
## 数组示例 awk 'BEGIN{x=0;i=0;} \ {name[x++]=$1;} \ END { for(;i<NR;i++){ print "name["i"] is",name[i]} }' mi_info # name[0] is mi6-1 # name[1] is mi6-2 # name[2] is minote3-1 # name[3] is minote3-2 # name[4] is mix2-1 # name[5] is mix2-2 # name[6] is mix2-3
正则表达式元字符
^ 行首定位符 $ 行尾定位符 . 匹配除换行之外的单个字符 \* 匹配0个或者多个前导字符(这里是前导字符0或者多个,任意一个或多个字符,使用 .* ) + 匹配一个或者多个前导字符 ? 匹配0个或者1个前导字符 [] 指定字符中的任意一个字符,比如[Ll] [a-z] [^] 上面一样,不匹配的字符 AA|BB 匹配AA或者BB (AB)+ 匹配一个或者多个AB组合,比如AB,ABAB,ABABAB... \* 匹配*本身 & 保存查找匹配到的串,可以用在后面的替换中 s/love/**&**/
内置函数
sub(/reg/,替换串[,目标串]) gsub(/reg/,替换串[,目标串]) index(str,sub_str) 返回sub_str第一次在str中出现的位置(偏移量从1开始) length(str) 返回字符串的字符个数 substr(str,start_pos[,length]) 返回子串,如果没有length,就到串的末尾 match(str,/reg/) 返回正则匹配在字符串中的位置,同时设置RSTART和RLENGTH的值 split(str,arr_name[,split_sig])
默认情况下每次调用rand(),结果都会产生相同的随机数,这时候需要调用srand()重新产生一个种子,后面的随机数才不同 ## 函数示例 awk 'BEGIN{ print rand(),rand(),srand(),rand(),rand();}' # 0.237788 0.291066 1 0.215969 0.629868 awk 'BEGIN{ print rand(),rand(),srand(),rand(),rand();}' # 0.237788 0.291066 1 0.556348 0.749557 awk 'BEGIN{ print rand(),rand(),srand(),rand(),rand();}' # 0.237788 0.291066 1 0.0931369 0.835396
条件语句和循环
## 语句和循环示例 (a) if # 在条件模式中,if是隐含的模式了,而条件语句if也可以按照需要直接声明出来的句式类似于 if () {} else if else {} awk '{ if( $1 ~ /note/) { print "note related."} else if ( $1 ~ /mix/ ) { print "mix related."} else { print "other ..."} }' mi_info # other ... # other ... # note related. # note related. # mix related. # mix related. # mix related. (b) while # 句法 while () {} awk 'BEGIN { i = 0; count = 0; } { while ( i < NR ) { i ++; if ( $1 ~ /note/ ) { count++; print NR, $1,$4,$5 } } } END { print "Count:",count }' mi_info # 3 minote3-1 6G 64G # 4 minote3-2 6G 128G # Count: 2
(c) for # 普通for循环,句法 for( ; ; ){} awk 'BEGIN { i = 0;} { for(;i<NR;i++) { if( $1 ~ /note/ ){ print NR,$1,$4,$5,"~~" } }}' mi_info # 3 minote3-1 6G 64G ~~ # 4 minote3-2 6G 128G ~~ (d) break continue # 同C/C++语言一样,是作用于跳出循环体和跳出本次循环的关键字。 ### 程序控制语句 (a) next # 从文件中读取下一行输入,然后从awk脚本顶部开始重新执行。同continue效果也有点相似,只不过这里是作用于awk工具在对每行操作的自动“循环”中的 (b) exit # 中断记录的处理,但是不能够跳过END语句块。exit可以带一个范围为0~255的退出参数,约定0表示成功,这个退出参数实际就传递给了$?表示执行的结果 awk '{ if ( $1 ~ /note/ ) { print NR,$1,$7,"skip"; next; } if ( $1 ~ /mix/ ) { print NR,$1,$7,"exit will"; exit 3; } print NR,$1,$7,"after if..."; } END { print "Fininal should be called here..." }' mi_info # 1 mi6-1 2499 after if... # 2 mi6-2 2899 after if... # 3 minote3-1 2499 skip # 4 minote3-2 2899 skip # 5 mix2-1 3299 exit will # Fininal should be called here... echo $? # 3
系统交互
## (a) 支持 > >> 重定向符号使用的时候作为文件名参数需要使用 "" 括起来,getline可以用于输入重定向来获得输入信息
awk 'BEGIN { "date" | getline date; print "The date is",date > "date.file"}'
cat date.file
# The date is Wed Dec 28 18:43:39 HKT 2016
## (b) 管道 |
awk '/note/ { print $0 | "grep 2499" }' mi_info
# minote3-1 5.5" 660 6G 64G 3500mAh 2499
## (c) system 函数。可以进行系统命令调用
awk 'BEGIN { system("whoami") }'
# root
## (d) printf 格式化输出信息,跟C语言的类似
awk 'BEGIN { printf "Hello, %s, you are %d years old.\n","Nicol TAO","23"}'
# Hello, Nicol TAO, you are 23 years old. 感谢各位的阅读,以上就是“awk使用示例分析”的内容了,经过本文的学习后,相信大家对awk使用示例分析这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是天达云,小编将为大家推送更多相关知识点的文章,欢迎关注!
|