通用线程: awk 实例,第 1 部分
来源:百度文库 编辑:神马文学网 时间:2024/06/05 12:51:05
通用线程: awk 实例,第 1 部分 [原文地址]
您应该会看到 /ect/passwd 文件中的内容,本文使用该文件来解释 awk 的工作原理。当调用 awk 时,我们指定 /etc/passwd 作为输入文件。Awk 在执行期间对 /etc/passwd 文件中的每一行依次执行 print 命令。所有输出都发送到 stdout,可以得到类似 cat 命令的结果。
现在解释代码块 { print }。在 Awk 中,花括号用于将代码分块,这与 C 语言类似。我们的代码块中只有一条 print 命令。在 Awk 中,当 print 命令单独出现时,将打印当前行的全部内容。 $ awk '{ print ? }' /etc/passwd
在 Awk 中,变量 ? 表示整个当前行,因此 print 和 print ? 的作用完全相同。 $ awk '{ print "" }' /etc/passwd
$ awk '{ print "hiya" }' /etc/passwd
运行该脚本,屏幕上讲显示多行 hiya。:)
$ awk -F":" '{ print ? ū }' /etc/passwd
halt7
operator11
root0
shutdown6
sync5
bin1
....etc.
print ? ū $ awk -F":" '{ print ? " " ū }' /etc/passwd
ū $ awk -F":" '{ print "username: " ? "\t\tuid:" ū }' /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.
FS=":"
}
{ print ? }
两种方法的区别在于如何设置字段分隔符。在该脚本中,(通过设置 FS 变量)在代码中指定字段分隔符,而前一示例通过在命令行向 awk 传递 -F":" 选项来设置 FS。一般而言,最好在脚本内部设置字段分隔符,因为这样可以少输入一个命令行参数。本文稍后将深入讲解 FS 变量。
通常,awk 会针对每个输入行执行一次每个代码块。但是,在许多编程情形下,可能需要在 awk 开始处理输入文件的文本之前 执行初始化代码。对这种情况,awk 支持定义 BEGIN 代码块。前一示例使用了这种代码块。因为 BEGIN 代码块在 awk 开始处理输入文件之前执行,因此它是初始化 FS(字段分隔符)变量、打印页眉或者初始化在后续程序中将要引用的其他全局变量的绝佳位置。
另外,awk 还提供了另一种称为 END 的专用代码块。在输入文件的所有行处理完毕之后,awk 执行这个代码块。通常,END 代码块用于进行最终计算或者打印应该在输出流结尾处出现的汇总信息。
/[0-9]+\.[0-9]*/ { print }
if ( ? ~ /root/ ) {
print ū
}
}
两个脚本的作用相同。第一个示例的布尔表达式位于代码块外,而第二个示例的代码块会针对每个输入行执行一次,本文使用 if 语句有选择地执行打印命令。两种方法都可以使用,可以选择与脚本的其他部分最匹配的方法。 if if {
if ( ? == "foo" ) {
if ( ū == "foo" ) {
print "uno"
} else {
print "one"
}
} else if (? == "bar" ) {
print "two"
} else {
print "three"
}
}
if ( ? !~ /matchme/ ) {
print ? ū ?
}
}
两个脚本都会只输出不 包含 matchme 字符序列的行。也可以选择最适合您的代码的方法。它们的功能完全相同。 ( ? == "foo" ) && ( ū == "bar" ) { print }
该示例只打印第一个字段等于 foo 且 第二字段等于 bar 的行。
在 BEGIN 代码块中,我们将整型变量 x 初始化为零。这样,awk 每次遇到空白行时都将执行 x=x+1 语句,递增 x 值。在所有行都处理完毕之后,awk 执行 END 代码块,并打印最终的汇总信息,以显示它找到的空白行数。
稍做试验就可以发现,如果特定变量不包含效数字,那么 awk 在计算数学表达式时将该变量当作数值零处理。
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 被设为单个空格字符,awk 将其解释为 “一个或多个空格或制表符”。在这个特定的示例中,默认的 FS 设置恰好是您最想要的设置。FS="foo[0-9][0-9][0-9]"
if ( NF > 2 ) {
print ? " " ū ":" ū
}
}
#skip header
if ( NR > 10 ) {
print "ok, now for the real information!"
}
}
Awk 还提供了一些具有多种用途的其他变量。后续文章中将深入讲解这些变量。
我们对 awk 的初次探究现在就结束了。随着本系列的延续,我将演示更高级的 awk 功能,我们将用一个真实的 awk 应用程序作为本系列的结尾。同时,如果急于学习更多知识,请参考下面列出的参考资料。
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 一起共度时光。可通过 [url=mailto:drobbins@gentoo.org?cc=drobbins@gentoo.org]drobbins@gentoo.org[/url] 与 Daniel 联系。
IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
分类: 未分类 | 修改 | 删除 | 推荐到分类 | 2009-12-19 00:03:43
来“口袋推推”看有多少人在关注你!
您应该会看到 /ect/passwd 文件中的内容,本文使用该文件来解释 awk 的工作原理。当调用 awk 时,我们指定 /etc/passwd 作为输入文件。Awk 在执行期间对 /etc/passwd 文件中的每一行依次执行 print 命令。所有输出都发送到 stdout,可以得到类似 cat 命令的结果。
现在解释代码块 { print }。在 Awk 中,花括号用于将代码分块,这与 C 语言类似。我们的代码块中只有一条 print 命令。在 Awk 中,当 print 命令单独出现时,将打印当前行的全部内容。 $ awk '{ print ? }' /etc/passwd
在 Awk 中,变量 ? 表示整个当前行,因此 print 和 print ? 的作用完全相同。 $ awk '{ print "" }' /etc/passwd
$ awk '{ print "hiya" }' /etc/passwd
运行该脚本,屏幕上讲显示多行 hiya。:)
$ awk -F":" '{ print ? ū }' /etc/passwd
halt7
operator11
root0
shutdown6
sync5
bin1
....etc.
print ? ū $ awk -F":" '{ print ? " " ū }' /etc/passwd
ū $ awk -F":" '{ print "username: " ? "\t\tuid:" ū }' /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.
FS=":"
}
{ print ? }
两种方法的区别在于如何设置字段分隔符。在该脚本中,(通过设置 FS 变量)在代码中指定字段分隔符,而前一示例通过在命令行向 awk 传递 -F":" 选项来设置 FS。一般而言,最好在脚本内部设置字段分隔符,因为这样可以少输入一个命令行参数。本文稍后将深入讲解 FS 变量。
通常,awk 会针对每个输入行执行一次每个代码块。但是,在许多编程情形下,可能需要在 awk 开始处理输入文件的文本之前 执行初始化代码。对这种情况,awk 支持定义 BEGIN 代码块。前一示例使用了这种代码块。因为 BEGIN 代码块在 awk 开始处理输入文件之前执行,因此它是初始化 FS(字段分隔符)变量、打印页眉或者初始化在后续程序中将要引用的其他全局变量的绝佳位置。
另外,awk 还提供了另一种称为 END 的专用代码块。在输入文件的所有行处理完毕之后,awk 执行这个代码块。通常,END 代码块用于进行最终计算或者打印应该在输出流结尾处出现的汇总信息。
/[0-9]+\.[0-9]*/ { print }
if ( ? ~ /root/ ) {
print ū
}
}
两个脚本的作用相同。第一个示例的布尔表达式位于代码块外,而第二个示例的代码块会针对每个输入行执行一次,本文使用 if 语句有选择地执行打印命令。两种方法都可以使用,可以选择与脚本的其他部分最匹配的方法。 if if {
if ( ? == "foo" ) {
if ( ū == "foo" ) {
print "uno"
} else {
print "one"
}
} else if (? == "bar" ) {
print "two"
} else {
print "three"
}
}
if ( ? !~ /matchme/ ) {
print ? ū ?
}
}
两个脚本都会只输出不 包含 matchme 字符序列的行。也可以选择最适合您的代码的方法。它们的功能完全相同。 ( ? == "foo" ) && ( ū == "bar" ) { print }
该示例只打印第一个字段等于 foo 且 第二字段等于 bar 的行。
在 BEGIN 代码块中,我们将整型变量 x 初始化为零。这样,awk 每次遇到空白行时都将执行 x=x+1 语句,递增 x 值。在所有行都处理完毕之后,awk 执行 END 代码块,并打印最终的汇总信息,以显示它找到的空白行数。
稍做试验就可以发现,如果特定变量不包含效数字,那么 awk 在计算数学表达式时将该变量当作数值零处理。
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 被设为单个空格字符,awk 将其解释为 “一个或多个空格或制表符”。在这个特定的示例中,默认的 FS 设置恰好是您最想要的设置。FS="foo[0-9][0-9][0-9]"
if ( NF > 2 ) {
print ? " " ū ":" ū
}
}
#skip header
if ( NR > 10 ) {
print "ok, now for the real information!"
}
}
Awk 还提供了一些具有多种用途的其他变量。后续文章中将深入讲解这些变量。
我们对 awk 的初次探究现在就结束了。随着本系列的延续,我将演示更高级的 awk 功能,我们将用一个真实的 awk 应用程序作为本系列的结尾。同时,如果急于学习更多知识,请参考下面列出的参考资料。
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 一起共度时光。可通过 [url=mailto:drobbins@gentoo.org?cc=drobbins@gentoo.org]drobbins@gentoo.org[/url] 与 Daniel 联系。
IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
通用线程: awk 实例,第 1 部分
通用线程:Awk 实例,第 2部分
通用线程 -- sed 实例,第 1 部分
通用线程 -- sed 实例,第 1 部分
通用线程 -- sed 实例,第 2 部分
通用线程 -- sed 实例,第 3 部分
通用线程:POSIX 线程详解,第 3 部分
Bash 实例,第 2 部分
Bash 实例,第 3 部分
实时 Java,第 3 部分: 线程化和同步
awk
WebSphere Application Server Community Edition 中的高级管理,第 2 部分: 使用线程池、集群和配置插件
Bash 实例,第一部分
驯服Java线程1
POSIX 线程详解-1
审计 PHP,第 1 部分: 理解 register_globals
FindBugs,第 1 部分: 提高代码质量
业务流程: 理解 BPEL4WS,第 1 部分
跨越边界: Streamlined,第 1 部分
Vim 实用技术,第 1 部分: 实用技巧
Ajax 和 REST,第 1 部分
Ajax 和 REST,第 1 部分
SOA 建模: 第 1 部分 服务识别
SOA 建模: 第 1 部分 服务识别