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包含了正则表达式所能匹配的内容长度

发表评论

邮箱地址不会被公开。 必填项已用*标注