awk是linux下一款很强大的文本处理工具,也可以方便的用在shell程序中完成对文本的处理。如果只是需要awk简单功能的话,语法很简单。前段时间学了一点,在此做下总结。

一、基本语法

按自己的理解来讲,awk是逐行对列进行操作的。换句话说,awk每次处理一行,对这一行的每个“域”处理完之后再处理下一行的域。域的划分方式可以自己指定,默认是以空格和制表符来分割。awk语句要在一对单引号内,所要做的操作要在一对花括号内,语法与c语言很类似,融汇贯通即可,如:

awk 'BEGIN {FS=":"} {print $1}' /etc/passwd

这条语句的意思是以":"作为分隔符,输出/etc/passwd文件的第一列。为什么最前面要加BEGIN这个关键字呢?因为awk在做任何操作之前会先读入一行文本,这样,第一行的分隔符就不是":"了。所以,加上BEGIN的目的就是让awk在读入第一行之前先把分隔符设定好。除了BEGIN关键字之外,还有END这个关键字,如:

awk 'BEGIN {FS=":";print "******"} {print $1} END {print "******"}' /etc/passwd

会以":"为分隔符,并且在最头和最尾输出"******"。

此外,花括号加在不同的位置,对程序含义有很大影响,如以下两段程序:

awk 'BEGIN {FS=":"} {if ($1=="root") $1="rot";print $1}' /etc/passwd
awk 'BEGIN {FS=":"} {if ($1=="root") {$1="rot";print $1}}' /etc/passwd

第一段程序会输出/etc/passwd文件第一列的全部内容,并把"root"变为"rot"输出,第二段程序只是把"root"变为"rot"输出,其他并未输出。

二、正则表达式

在awk中使用正则表达式要用//括起来,如匹配"passwd"这个字符串,语法是/passwd/。举个例子,在/etc/passwd文件的第一列匹配"root"关键字,如果匹配到则输出整行,如果匹配不到则不输出。

awk 'BEGIN {FS=":"} {if ($1~/root/) print $0}' /etc/passwd

三、内置变量和字符串函数

awk中最常用的三个内置变量是FS、NF、NR,三者的含义分别为分隔符、当前处理的域(数字)、当前行(数字)。

awk内置的字符串函数主要有gsub(r,s),gsub(r,s,t),index(s,t),length(s),match(s,r),split(s,a,fs),sub(r,s),substr(s,p),substr(s,p,n)

1、gsub(r,s)

在$0上用s替换r

2、gsub(r,s,t)

在t上用s替换r

3、index(s,t)

定位出t在s中的位置

4、length(s)

顾名思义

5、match(s,r)

与index类似,不过此时r可以用正则表达式

6、split(s,a,fs)

将s以分隔符fs分隔开,放入数组a中,如:

awk 'BEGIN {print split("1*2*3",a,"*")}'

为什么要加"BEGIN"呢,按我的理解,awk在开始执行命令语句之前,会读取后面文件的一行内容作为输入,但如果后面不接任何文件,awk就会一直卡在那儿,所以,加上BEGIN的目的就是为让awk在读取文件内容之前就执行命令,不会让它卡住。

7、sub(r,s)

以s替换r,与gsub不同的是,sub只执行一次替换。

8、substr(s,p)

输出字符串s中第p个字符及之后的字符,如:

awk 'BEGIN {FS=":"} {print substr($1,1,3)}' /etc/passwd

输出/etc/passwd中第一个字段中三个字符的数据。