awk用于对行和列进行操作,而且内置了诸如数组 函数等操作,非常的灵活
awk的脚本的结构如下
awk ‘BEGIN{print “start” }pattern{coommands}
END{print “end”}
file
awk命令也能够读取stdin的内容
一个awk的脚本由3部分组成 BEGIN语句块,END语句块,和通用语句块
这3个部分是可选的,其中任何一个部分都可以不书写
脚本包含在单引号或者双引号之中
awk ‘BEGIN{statements}{statements} END {statements}’
例如
awk ‘BEGIN{i=0}'{i++} END{print i} filename
使用双引号也是可以的
1.BEGIN{commands} 语句块中的语句
2.从文件中或者stdin中读取一行,然后指定Pattern {commands},重复这个流程,直到文件读取完成
3.读取完成输入流后,执行END{commands}语句块
BEGIN语句块在awk开始从输入流中读取行之前被执行,可以将一些打印的表头存入语句块中
END语句块和BEGIN语句块类似,END语句块在awk从输入流读取完成后执行,可以打印一些汇总信息,也是一个可选的语句块
pattern中的语句块也是可选的,如果不提供的话,会默认执行{ print } awk对于读取到的每一行,都会执行这个语句块,这就好比一个用于读取行的while循环,在循环体中提供了相对应的语句
每次读取一行的时候,就会检查这行和提供的样式是否匹配,样式可以是正则表达式,如果匹配了样式,那么会执行{ } 中的语句
样式是可选的,如果没有提供样式,会默认所有的行都匹配
首先看没有提供的样式
echo -e “line1\nline2” |awk ‘BEGIN{print “START”}{print}END{print “END”}’
START
line1
line2
END
{ } 类似于一个循环体,会对文件中每一行进行迭代
我们一般会将初始化变量语句放在BEGIN,在END语句中,放入打印结果
awk是具有一些重要功能的
NR:表示记录数量 number of records 执行过程中当前的行号
NF:表示字段数量 number of fields 在执行过程中对应于当前行的字段数
$0:这个变量包含执行过程中当前行的文本内容
$1:这个变量包含第一个字段的文本内容
$2:这个变量包含了第二个字段的文本内容
例如
echo -e “line f2 f3\nline2 f4 f5\nline3 f6 f7” | \
awk ‘{
print “Line no:”NR”,No of fields :”NF, “$0=”$0,”$1=”$1,”$2=”$2,”$3=”$3
}’
Line no:1,No of fields :3 $0=line f2 f3 $1=line $2=f2 $3=f3
Line no:2,No of fields :3 $0=line2 f4 f5 $1=line2 $2=f4 $3=f5
Line no:3,No of fields :3 $0=line3 f6 f7 $1=line3 $2=f6 $3=f7
我们可以使用print $NF打印一行中最后一个字段,用$(NF-1)打印倒数第二个字段,依次类推,
printf()函数在awk中也可以使用,我们使用这个函数来代替print
awk还有一些基本的用法
打印每一行的第二个和第三个字段
awk ‘{print $3,$2}’ file
要统计行数,使用下面的命令
awk ‘END{print NR}’ file
NR 就能获得文件的所有行数
我们可以将每一行的一个字段,按照下面的方式进行累加
将外部的变量传递给awk
借助-v,我们可以将外部的值传递给awk
$VAR=100000
$echo | awk -v VARIABLE=$VAR'{print VARIABLE}’
将多个外部变量传递给awk,例如
在外部定义多个外部变量
var1=”Var1″;var2=”Var2″
echo | awk ‘{print v1,v2}’ v1=$var1 v2=$var2
使用getline去读取行
grep 默认读取一个文件的所有行,如果只想着读取某一行,那么可以使用getline函数
有时候,我们需要从BEGIN语句块中读取第一行
getline var
将这一行赋值给变量var
不使用var,则会默认赋值给$0,$1,$2变量
具体的使用方式如下
$ seq 5|awk ‘BEGIN {getline;print “Read ahead first line,”$0}{print $0}’
awk处理进行过滤
我们需要处理的行指定一些条件
用样式对awk处理的行进行过滤
awk ‘NR < 5’
awk ‘NR==1,NR==4’ 行号在1-5之间的行
awk ‘/linux/’ 包含Linux的行
awk ‘!/linux/’不包含Linux的行
设置字段定界符
默认的定界符是空格,我们可以使用 -F “delimiter”来指定一个定界符
awk -F: ‘{print $NF}’ /etc/passwd
awk ‘BEGIN {FS=”:”}{print $NF}’ /etc/passwd
在BEGIN语句块中可以用OFS=”delimiter”设置输出字段的定界符
awk命令可以使用for循环
for(i=0;i<10;i++){print $i;}
或者
for(i in array){print array[i]}
awk有很多内建的字符串控制函数,我们认识一下其中的部分函数
length(String) 获取到字符串的长度
index(string,search_String) 返回search_string在string中的位置
split(String,array,delimiter) 使用定界符来生成一个列表,并存入这个数组
substr(string,start-position,end-position)字符串中用字符起止偏移量生成子串,并返回子串
sub(regex,replacement_str,string)将正则变道时匹配的第一处内容替换成replacment_str
gsub(regex,replacment_str,string)这个函数会替换正则表达式匹配的所有内容
match(regex,string),检查正则表达式能够匹配字符串?能就返回非0,不然就是返回0
而且可以传入RSTART,RLENGTH,变量RSTART包含正则表达式所匹配的起始内容,变量RLENGTH包含了正则表达式所能匹配的内容长度