zz 通用线程: awk 实例,第 1 部分
2011-11-27 18:41
253 查看
通用线程: awk 实例,第 1 部分
一种名称很奇特的优秀语言介绍Daniel Robbins (drobbins@gentoo.org), 总裁兼 CEO, Gentoo Technologies, Inc.
简介: Awk 是一种名称奇怪但功能强大的语言。本文是一个包含三部分的系列的第一篇。在本文中,DanielRobbins 将使您迅速掌握 awk 编程技巧。随着本系列的进展,将讨论更高级的主题,最后将演示一个真实的高级 awk 应用程序。
标记本文!
发布日期: 2008 年 7 月 28 日 (最初发布 2000 年 12 月 01 日)
级别: 初级
其他语言版本: 英文
访问情况 : 14879 次浏览
评论: 2 (查看 | 添加评论 - 登录)
![](http://dw1.s81c.com/developerworks/i/stars120x20-4b.jpg)
平均分 (26个评分)
为本文评分
捍卫 awk
在这一系列的文章中,我将使您成为精通 awk 的编程人员。我承认,awk 并没有一个非常好听且又非常 “时髦” 的名字。awk 的 GNU 版本(叫作 gawk)听起来非常怪异。那些不熟悉这种语言的人可能听说过 "awk",而且可能认为它是一组落伍且过时的混乱代码。它甚至会使最博学的 UNIX 权威陷于混乱的边缘(使他不断地发出 "kill -9!" 命令,就象使用咖啡机一样)。
的确,awk 没有一个动听的名字。但它是一种很棒的语言。awk 适合于文本处理和报表生成,它还有许多精心设计的特性,允许进行多种方式的编程。与某些语言不同,awk 的语法较为常见。它借鉴了某些语言的一些精华部分,如 C 语言、python 和 bash(虽然在技术上,awk 比 python 和 bash 早创建)。awk 是一种一旦学会就会成为您战略代码库的重要部分的语言。
回页首
第一个 Awk
您应该会看到 /ect/passwd 文件中的内容,本文使用该文件来解释 awk 的工作原理。当调用 awk 时,我们指定 /etc/passwd 作为输入文件。Awk 在执行期间对 /etc/passwd 文件中的每一行依次执行 print 命令。所有输出都发送到 stdout,可以得到类似 cat 命令的结果。
现在解释代码块
{ print }。在 Awk 中,花括号用于将代码分块,这与 C 语言类似。我们的代码块中只有一条 print 命令。在 Awk 中,当 print 命令单独出现时,将打印当前行的全部内容。
$ awk '{ print $0 }' /etc/passwd |
$0表示整个当前行,因此
print $0的作用完全相同。
$ awk '{ print "" }' /etc/passwd |
$ awk '{ print "hiya" }' /etc/passwd |
回页首
多个字段
print $1
$ awk -F":" '{ print $1 $3}' /etc/passwd |
halt7 operator11 root0 shutdown6 sync5 bin1 ....etc. |
print $1 $3
$ awk -F":" '{ print $1 " " $3 }' /etc/passwd |
$1
$3
$ awk -F":" '{ print "username: " $1 "\t\tuid:" $3 }' /etc/passwd |
username: halt uid:7 username: operator uid:11 username: root uid:0 username: shutdown uid:6 username: sync uid:5 username: bin uid:1 ....etc. |
外部脚本
BEGIN { FS=":" } { print $1 } |
回页首
BEGIN 与 END 代码块
通常,awk 会针对每个输入行执行一次每个代码块。但是,在许多编程情形下,可能需要在 awk 开始处理输入文件的文本之前 执行初始化代码。对这种情况,awk 支持定义 BEGIN 代码块。前一示例使用了这种代码块。因为 BEGIN 代码块在 awk 开始处理输入文件之前执行,因此它是初始化 FS(字段分隔符)变量、打印页眉或者初始化在后续程序中将要引用的其他全局变量的绝佳位置。
另外,awk 还提供了另一种称为 END 的专用代码块。在输入文件的所有行处理完毕之后,awk 执行这个代码块。通常,END 代码块用于进行最终计算或者打印应该在输出流结尾处出现的汇总信息。
回页首
正则表达式与代码块
/foo/ { print } |
/[0-9]+\.[0-9]*/ { print } |
表达式与代码块
fred
$1 == "fred" { print $3 } |
root
$5 ~ /root/ { print $3 } |
条件语句
if
{ |
if语句有选择地执行打印命令。两种方法都可以使用,可以选择与脚本的其他部分最匹配的方法。
if
if
{ |
if
! /matchme/ { print $1 $3$4 } |
{ |
matchme字符序列的行。也可以选择最适合您的代码的方法。它们的功能完全相同。
( $1 == "foo" ) && ( $2 == "bar" ) { print } |
foo且 第二字段等于
bar的行。
回页首
数值变量!
在 BEGIN 代码块中,我们将整型变量
x初始化为零。这样,awk 每次遇到空白行时都将执行
x=x+1语句,递增
x值。在所有行都处理完毕之后,awk 执行 END 代码块,并打印最终的汇总信息,以显示它找到的空白行数。
回页首
字符串化变量
2.01 |
1.01
x
$( )
1.01
{ print ($1^2)+1 } |
回页首
众多运算符
Awk 的另一个优点是它拥有全面的数学运算符。除了标准的加减乘除,awk 还支持前面演示的指数运算符 “^”、求模(余数)运算符 “%” 和借鉴自 C 语言的大量方便的赋值运算符。
其中包括前后加/减(
i++、
--foo),加减乘除赋值运算符(
a+=3、
b*=2、
c/=2.2、
d-=6.2)。而且,这仅仅是一部分 —— 我们还能使用方便的求模/指数赋值运算符(
a^=2、
b%=4)。
回页首
字段分隔符
Awk 有其自己的特殊变量集合。其中一些变量支持调优 awk 性能,而且可以读取另一些变量来收集关于输入的重要信息。前面已经接触过特殊变量 FS。如前所述,这个变量支持设置 awk 期望在字段中找到的字符序列。当我们使用 /ect/passwd 作为输入时,FS 设为 ":"。尽管这样做可以解决问题,但 FS 还支持更高的灵活性。
FS="\t+" |
FS="[[:space:]+]" |
FS="foo[0-9][0-9][0-9]" |
字段数目
{ |
记录数目
{ |
我们对 awk 的初次探究现在就结束了。随着本系列的延续,我将演示更高级的 awk 功能,我们将用一个真实的 awk 应用程序作为本系列的结尾。同时,如果急于学习更多知识,请参考下面列出的参考资料。
参考资料
您可以参阅本文在 developerWorks 全球站点上的 英文原文。
如果喜欢优秀的传统书籍,那么 O'Reilly 出版的 sed & awk, 2nd Edition 是不错的选择。
查阅 comp.lang.awk FAQ。其中还包含许多额外的 awk 链接。
Patrick Hartigan 的 awk 教程 附带了一些实用的 awk 脚本。
关于作者
![](http://www.ibm.com/developerworks/cn/i/robbins.gif)
Daniel Robbins 居住在新墨西哥州的 Albuquerque。他是 Gentoo Technologies, Inc. 的总裁兼 CEO, Gentoo Linux(用于 PC 的高级 Linux)和 Portage 系统(Linux 的下一代移植系统)的创始人。他还是 Macmillan 书籍 Caldera OpenLinux Unleashed、 SuSE Linux Unleashed 和 Samba Unleashed 的合作者。Daniel 自二年级起就与计算机某些领域结下不解之缘,那时他首先接触的是 Logo 程序语言,并沉溺于 Pac-Man 游戏中。这也许就是他至今仍担任 SONY Electronic Publishing/Psygnosis 的首席图形设计师的原因所在。Daniel 喜欢与妻子 Mary 和新出生的女儿 Hadassah 一起共度时光。可通过 drobbins@gentoo.org 与 Daniel 联系。
相关文章推荐
- zz 通用线程:Awk 实例,第 2部分
- 通用线程:Awk 实例,第 1部分
- 通用线程:Awk 实例,第 2部分
- zz 通用线程:Awk 实例,第 3部分
- 通用线程:awk 实例,第 1 部分:一种名称很奇特的优秀语言介绍
- 通用线程:Awk 实例,第 2部分
- 通用线程:Awk 实例 1
- 通用线程:Awk 实例 2
- 通用线程:Awk 实例 3
- awk使用 第7部分 awk对多行数据的处理实例
- 通用线程 -- sed 实例
- 通用线程:POSIX 线程详解,第 2部分
- 通用线程: 学习 Linux LVM,第 1 部分
- Awk 实例,第 3 部分
- 通用线程 -- sed 实例二
- 通用线程:POSIX 线程详解,第 2部分 互斥对象
- 通用线程:POSIX 线程详解,第 3 部分
- 通用线程:POSIX 线程详解,第 2部分
- 通用线程:POSIX 线程详解,第 2部分
- 通用线程 -- sed 实例三