AWK可以说是一种语言,他有着自己的语法,可以实现函数定义,变量赋值,条件选择(循环,判断,选择)…总之是值得深入研究一下的。
AWK的起源:是个报告生成器,可以格式化文本输出内容,它的命名是由Aho,Weinberger,Kernighan三位作者首字母组合而成的,他有多个版本:New awk(nawk),GNU awk(gawk)。
gawk称为模式扫描和处理语言,它的基本用法如下:
awk [options] 'program' var=value file…
awk [options] -f programfile var=value file…
awk [options] 'BEGIN{action;…}pattern{action;…}END{action;…}' file
awk程序通常由:BEGIN语句块,能使用模式匹配的通用语句块,END语句块,共三部分
program通常是存放在单引号中
[options]:
-F 指明输入使用道德字段分隔符
-v var=value:自定义变量
pattern和action:
a.pattern部分决定动作语句何时触发及触发事件(BEGIN,END)
b.action statements对数据进行处理,放在{}内指明(print,printf)
分隔符,域和记录:
1.awk执行时,由分隔符分割的字段(域)标记$1,$2…$n称为域标识,$0为所有域
注意:和shell中变量$符含义不同
2.文件的每一行称为记录
3.省略action,则默认执行print $0操作
awk工作原理:
STEP1:执行BEGIN{action;…}语句块中的语句
STEP2:从文件或标准输入(stdin)读取一行,然后执行pattern{action;…}语句块,他逐行扫描文件,从第一行到最后一行重复这个过程,知道文件全部被读取完毕
STEP3:当读至输入流末尾时,执行END{action;…}语句块
BEGIN语句块在awk开始从输入流中读取行之前被执行,这是一个可选的语句块,比如变量初始化,打印输出表格的表头等语句通常卸载BEGIN语句块中
END语句块在awk从输入流中读取玩完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,他也是可选语句块
pattern语句块中的通用命令是最重要的部分,也是可选的,如果没有提供pattern语句块,则默认执行{print},即打印每一个读取到的行,awk读取的每一行都会执行该语句块。
print格式:print item1,item2…
要点:
1)逗号分隔符
2)输出的各item可以是字符串,也可以是数值,当前记录的字段,变量或者awk表达式
3)省略item,相当于print $0
awk变量:
变量:内置和自定义变量
FS:输入字段分隔符,默认为空白字符
OFS:输出字段分隔符,默认为空白字符
RS:输入记录分隔符,指定输入时的换行符,原换行符仍有效
awk -v RS=' ' '{print }' /etc/passwd
ORS:输出记录分隔符,输出时用指定符号代替换行符
awk -v ORS=' ' '{print }' /etc/passwd
NF:字段数量
awk -F: '{print NF}' /etc/fstab
awk -F: '{print $(NF-1)}' /etc/fstab
NR:显示行号
行号是每读一行就显示该行号,而不是一次性显示共有多少行
FNR:显示每个文件的行号,单独计数
FILENAME:当前文件名
awk '{print FILENAME}' /etc/fstab
ARGC:命令行参数
awk '{print ARGC}' /etc/fstab
结果显示2,它有两个参数,第一个参数是awk自身,第二个参数为/etc/fstab
ARGV:数组,保存的是命令行搜给定的各参数
awk 'BEGIN{print ARGV[0]}' /etc/fstab –> awk
AWK变量:
自定义变量
1)-v var=value
变量名区分字符大小写
2)在program中直接定义
awk 'BEGIN{"name"="awk";print name}'
printf命令:
格式化输出:printf "FORMAT",item1,item2,…
1)必须指定FORMAT
2)不会自动换行,需要显示给出换行控制符\n
3)FORMAT中需要分别为后面每个item指定格式符
格式符:与item一一对应
修饰符:
#[.#]:第一个数字控制显示的宽度,第二个数字表示小数点后的精度,%3.1f
-:左对齐(默认右对齐)%-10s
+:显示数值的正负符号 %+d
操作符:
算数操作符:
+,-,*,/,%,^
字符串操作符:
没有符号的操作符,字符串连接
赋值操作符:
=,+=,-=,*=,/=,%=,^=,++,–
比较操作符:
>,>=,<,<=,!=,==
模式匹配符:
~:左边是否和右边匹配包含
!~:是否不匹配
逻辑操作符:
awk -F: '$3>=0&&$3<=1000{print $1}' /etc/passwd 显示所有系统用户的用户名
awk -F: '$3==0||$3>1000{print $1}' /etc/passwd 显示root或者普通用户
Pattern模式:
根据pattern条件,过滤匹配的行,再做处理
1)如果未指定:空模式,匹配每一行
2)/regular expression/:仅处理能够模式匹配到的行,需要用/ /括起来
awk '/^root/{print }' /etc/passwd
3) relation expression:关系表达式,结果有真有假,结果为真时才会被处理
真:结果为非0值,非空字符串
假:结果为空字符串
seq 10 | awk 'i=!i'
此执行结果为显示奇数行,seq 10 生成1~10的序列,i的初始值为0,!i则表示为非0,即为真,这样第一行就打印出来了,i=!i则i现在值为1,第一行结束,读第二行,!i,即非1,为假,所以这一行就不输出了,然后i被赋值为0,然后就这样继续循环下去,知道将序列中所有元素都读完,这样打印显示的就是奇数行
4)line ranges:行范围
startline,endline:/part1/,/part2/不支持直接给出数字格式
awk -F: '/^root/,/^nobody/{print $1,$3}' /etc/passwd
5) BEGIN/END模式
BEGIN{}:仅在开始处理文本中的文本之前执行一次
END{}: 仅在文本处理完成后执行一次
AWK ACTION
常用的action分类:
1)Expression:算术,比较表达式等
2)Control Statements:if,while等
3)Compound Statements:组合语句
4)Input Statements
5)Output Statements:print等
控制语句之if-else
语法:
if(condition)statmement[else statement]
if(condition1){statement1}else if{condition2}{statement2}else{statement3}
使用场景:对awk取得的整行或某个字段做条件判断
控制语句之while循环
语法:while(condition)statement
条件‘真’,进入循环;条件‘假’,退出循环
使用场景;
对一行内的多个字段逐一类似处理时使用
对数组中的各元素逐一处理时使用
控制语句之do-while循环
语法:do statement while(condition)
意义:无论真假,先执行一次循环体
控制语句之for循环
语法:for(expr1,expr2,expr3…)statement
for(variable assignment;condition;iteration process){for-body}
特殊用法:能够遍历数组中的元素
语法:for(var in array){for-body}
参考性能方面的数据,可以知道awk的语句执行效率比其他几种循环遍历要高
控制语句之switch
语法:switch(expression){case value1 or /regexp/:statement;case value2 or /regexp2/:statement;…default:statement}
break,continue,next
break是退出循环体:break[n]
continue是退出本次循环,开始新的一轮循环:continue[n]
next提前结束对本行处理而直接进入下一行处理(awk自身循环)
awk -F: '{if($3%2!=0)next;print $1,$3}' /etc/passwd
awk数组
若要遍历数组中的每一个元素,要使用for循环
for(var in arry){for-body}
var会遍历数组array中的每一个索引
awk函数
数值处理:
rand():返回0和1之间一个随机数
awk 'BEGIN{srand();for(i=1;i<=10;i++)print int(rand()*100)}'
字符串处理:
length([s]):返回指定字符串的长度
sub(s,r[,t]):对t字符串进行搜索s表示的模式匹配的内容,并将第一个匹配的内容替换为r
gsub(s,r[,t]):对t字符串进行搜索s表示的模式匹配的内容,并将所有能匹配的内容替换为r
split(s,array[,r]):以r分隔符切割s,并将切割后的结果保存在array所表示的数组中
自定义函数:
格式:
function name(para1,para2…){
statements
return expression
}
awk中调用shell命令
system命令:
空格是awk中字符串连接符,如果system中需要使用awk中的变量可以使用空格分隔,或者说除了awk的变量外其他一律用""引用起来
awk 'BEGIN{system("hostname")}'
awk 'BEGIN{a="awk";system("echo " a)}'
将awk程序携程脚本,直接调用或执行
也可以向awk脚本传递参数
格式:
awk.awk var=value var2=value2 …inputfile
原创文章,作者:Stupid_L,如若转载,请注明出处:http://www.178linux.com/48048