首页 理论教育 实用LinuxShell编程:awk文本处理

实用LinuxShell编程:awk文本处理

时间:2023-11-18 理论教育 版权反馈
【摘要】:awk是Unix/Linux下一种优秀的用于处理文本的编程语言工具。awk最基本的命令格式为:awk对文件进行逐行扫描并处理。假设有一个文件team.txt,一共4列,内容分别为名字、工号、生日、工资,用awk可以显示这个文件的内容:其中,$0代表awk读入的文件的每一整行内容,这里的print是awk中的命令,不是Linux命令。多数情况下,awk是文本输入驱动的。具体执行结果如下:awk还有其他字符串处理函数,这里就不一一列举了。

实用LinuxShell编程:awk文本处理

与sed一样,awk并不是Bash的一部分,但事实上几乎所有的Linux系统都安装了sed与awk,并且,常常见到Bash脚本里面有调用sed与awk的命令。awk是Unix/Linux下一种优秀的用于处理文本的编程语言工具。与其他大多数Linux命令不同的是,仅从名字上看,猜不出awk的功能。awk的名称来自它的三个创始人Alfred Aho、Peter Weinberger和Brian Kernighan的姓氏的首字母。

awk最基本的命令格式为:

978-7-111-48202-4-Chapter08-182.jpg

awk对文件进行逐行扫描并处理。假设有一个文件team.txt,一共4列,内容分别为名字、工号、生日、工资,用awk可以显示这个文件的内容:

978-7-111-48202-4-Chapter08-183.jpg

其中,$0代表awk读入的文件的每一整行内容,这里的print是awk中的命令,不是Linux命令。命令awk'{print$0}'team.txt与命令cat team.txt的效果相同,awk依次读取文件team.txt的每一行并且打印出来。

下面的命令只显示名字和工资,并加上序号

978-7-111-48202-4-Chapter08-184.jpg

978-7-111-48202-4-Chapter08-185.jpg

其中,$1表示文件的第1列,即名字;$4表示第4列,即工资;NR(Number of the current Record)为awk的内置变量,表示当前记录(即当前行)的序号。

下面的例子,awk依次读取文件team.txt的每一行并输出Good morning,因为team.txt一共有四行,所以输出了四次Good morning:

978-7-111-48202-4-Chapter08-186.jpg

通过上面的例子,可以进一步理解awk的“逐行扫描”。多数情况下,awk是文本输入驱动的。如果要输出Good morning,运行awk'{print"Good morning"}'这个没有文本输入的命令是不行的:

978-7-111-48202-4-Chapter08-187.jpg

这个命令将没有任何输出,因为awk在等待文本输入(命令中不含有文件名,靠文本输入驱动的awk在等待键盘输入),键盘输入任何字符串,就会输出Good morning:

978-7-111-48202-4-Chapter08-188.jpg

难道让awk做点事情必须要有文本输入驱动吗?其实也不是这样的,后面要讲到的awk的BEGIN模块可以解决这个问题。

awk支持正则表达式,基本的命令格式为:

978-7-111-48202-4-Chapter08-189.jpg

例如,想知道工号为3578的人的信息,用如下命令,其中$2~3578表示第二列匹配3578:

978-7-111-48202-4-Chapter08-190.jpg

想知道1971年出生的人的名字,用如下命令:

978-7-111-48202-4-Chapter08-191.jpg

awk自身有重定向输出功能。下例中,awk取出了team.txt的第1列和第4列,另存为wage.txt文件:

978-7-111-48202-4-Chapter08-192.jpg

前面提到了两种awk的基本命令格式,还有一种较常用的格式为:

978-7-111-48202-4-Chapter08-193.jpg

-F后面带域分隔符,默认的域分隔符是空格。前面的几个例子中,数据的域分隔符是空格,所以awk命令都省略了选项-F。

978-7-111-48202-4-Chapter08-194.jpg

显然,文件/etc/passwd的域分隔符是:,要查看Linux账号和对应的默认shell,用下面的命令:

978-7-111-48202-4-Chapter08-195.jpg

实际上-F后面跟的域分隔符指的是输入域分隔符(/etc/passwd是awk命令的输入文件),输入域分隔符也可以由awk的内置变量FS指定;相应地,输出域分隔符由awk的内置变量OFS指定,它们的默认值都是空格。例如,查看Linux账号和对应的默认shell,输出的两列用#分隔:

978-7-111-48202-4-Chapter08-196.jpg

与Perl语言一样,awk有BEGIN和END模块。简单地说,BEGIN模块总是最先执行,END模块总是最后执行。例如,可以使用BEGIN模块给team.txt加文件头:

978-7-111-48202-4-Chapter08-197.jpg

下面使用END模块计算并打印平均工资,由结果可知,这几个人的平均工资为2975元:(www.xing528.com)

978-7-111-48202-4-Chapter08-198.jpg

不管位置的先后,BEGIN模块最先执行,END模块最后执行。如下例所示,awk先执行BEGIN模块,打印Morning,然后读文件team.txt,该文件一共四行,所以打印了四次Mary,最后执行END模块,打印Bye:

978-7-111-48202-4-Chapter08-199.jpg

前面讲过,在多数情况下,awk需要文本输入来驱动。在没有文本输入的情况下要想输出Good morning,可以用BEGIN模块:

978-7-111-48202-4-Chapter08-200.jpg

awk具有与C语言十分类似的流程控制功能,如if和if/else条件控制,while、do-while和for循环,用于跳转或者退出的命令break、continue、next和exit等。例如,打印工资高于3000元的人的信息:

978-7-111-48202-4-Chapter08-201.jpg

可知,一共有两个人的工资高于3000元。下面的例子,打印出第一个工资高于3000元的人的信息后,马上执行exit,程序退出了,所以只打印了一个人的信息:

978-7-111-48202-4-Chapter08-202.jpg

awk有内置的数学函数,这些函数是Bash所没有的,见表8-6。

表8-6 awk的数学函数

978-7-111-48202-4-Chapter08-203.jpg

例如,int(15.68)输出整数部分15,sqrt(3)输出3的平方根1.73205:

978-7-111-48202-4-Chapter08-204.jpg

因为team.txt有四行,所以下面的命令打印出四个0到1之间的随机数

978-7-111-48202-4-Chapter08-205.jpg

awk提供了字符串处理函数,例如,index("Mississippi","is")返回子字符串is在字符串Mississippi中首次出现的位置;substr("707-555-1111",1,3)返回字符串707-555-1111从第1个到第3个字符组成的子字符串;length("abcdefghij")返回字符串abcdefghij的长度。具体执行结果如下:

978-7-111-48202-4-Chapter08-206.jpg

awk还有其他字符串处理函数,这里就不一一列举了。

与Perl语言一样,awk提供了系统调用函数system。例如,awk调用Linux命令date,查看日期和时间:

978-7-111-48202-4-Chapter08-207.jpg

awk还可以应用system函数调用其他shell或者Perl脚本,这为混合编程提供了方便。

前面的例子,给人一种感觉,似乎awk只有命令行形式。其实,awk也可以像Bash样写成脚本,格式为:

978-7-111-48202-4-Chapter08-208.jpg

下面脚本factorial_1.awk的功能是计算并打印出6到10的阶乘:

978-7-111-48202-4-Chapter08-209.jpg

脚本factorial_1.awk中使用了格式化打印命令printf,awk的printf与C语言的printf在基本语法上几乎完全一致。

执行awk-f命令,可打印出6到10的阶乘:

978-7-111-48202-4-Chapter08-210.jpg

如果将awk-f加入到脚本的第一行,得到脚本factorial_2.awk:

978-7-111-48202-4-Chapter08-211.jpg

那么,直接运行factorial_2.awk脚本,即可打印出6到10的阶乘:

978-7-111-48202-4-Chapter08-212.jpg

awk有两个与C语言类似的内置变量ARGC和ARGV,用于读取命令参数。awk还有内置数组变量ENVIRON,可用来读取当前系统的环境信息等。awk是一门脚本编程语言,内容很多,这里不展开讲解。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈