分类: LINUX
2010-03-19 17:23:05
张丽霞
前面一篇文章《awk简介》给大家简单介绍了awk,这篇文章开始,将陆续通过具体例子讲解awk的用法。为了讲解方便,将前篇文章中的address.in文件稍作修改,内容如下:
1:abc:male:13612345678
2:mary:female:12345678
3:aaa:female:44445555
4:zlx:female:13550000000
5:lucy:female:13611111111
6:david:male:10101010
7:anotherzlx:male:12125656
8:aaazlxbcd:male:12125656
9:zlxzlx:male:00000000
将脚本作为命令行自变量传递给 awk 对于小的单行程序来说是非常简单的,而对于多行程序,它就比较复杂。这样我们就需要在外部文件中撰写脚本。然后可以向 awk 传递 -f 选项,以向它提供此脚本文件。例如,我们在test.awk中键入内容如下:
BEGIN {
FS=":"
}
{print $1 }
然后在命令行键入如下命令:
awk -f test.awk address.in
则执行结果如下:
1
2
3
4
5
6
7
8
9
可见这个多行脚本与原来的单行脚本的作用相同,它们都打印出 address.in 中每一行的第一个字段。这两个方法的差别在于如何设置字段分隔符。在这个脚本中,字段分隔符在代码自身中指定(通过设置 FS 变量),而在前一个示例中,通过在命令行上向 awk 传递 -F":" 选项来设置 FS。通常,最好在脚本自身中设置字段分隔符,这样可以少输入一个命令行自变量。
那么代码中的BEGIN是什么意思呢?通常,对于每个输入行,awk 都会执行每个脚本代码块一次。然而,在许多编程情况中,可能需要在 awk 开始处理输入文件中的文本之前执行初始化代码。对于这种情况,awk 允许您定义一个 BEGIN 块。我们在前一个示例中使用了 BEGIN 块。因为 awk 在开始处理输入文件之前会执行 BEGIN 块,因此它是初始化 FS(字段分隔符)变量、打印页眉或初始化其它在程序中以后会引用的全局变量的极佳位置。awk 还提供了另一个特殊块,叫作 END 块。awk 在处理了输入文件中的所有行之后执行这个块。通常,END 块用于执行最终计算或打印应该出现在输出流结尾的摘要信息。
下面开始讲解规则表达式和块。awk 允许使用规则表达式,根据规则表达式是否匹配当前行来选择执行独立代码块。以下示例脚本只输出包含字符序列 zlx的那些行:
/zlx/ {print }
结果如下:
4:zlx:female:13550000000
7:anotherzlx:male:12125656
8:aaazlxbcd:male:12125656
9:zlxzlx:male:00000000
当然,可以使用更复杂的规则表达式。以下脚本将只打印包含浮点数的行:
/[0-9]+\.[0-9]*/ { print }
接下来我们来看表达式和条件语句。awk中有许多其它方法可以选择执行代码块。我们可以将任意一种布尔表达式放在一个代码块之前,以控制何时执行某特定块。仅当对前面的布尔表达式求值为真时,awk 才执行代码块。以下示例脚本输出将输出其第二个字段等于 zlx 的所有行中的第四个字段。如果当前行的第一个字段不等于 zlx,awk 将继续处理文件而不对当前行执行 print 语句:
$2 == "zlx" { print $4 }
结果如下:
13550000000
除了"=="之外,awk还提供了完整的比较运算符集合,包括 "<"、">"、"<="、">=" 和 "!="。另外,awk 还提供了 "~" 和 "!~" 运算符,它们分别表示“匹配”和“不匹配”。它们的用法是在运算符左边指定变量,在右边指定规则表达式。如果某一行的第二个字段包含字符序列 zlx,那么以下示例将只打印这一行中的第四个字段:
$2 ~ /zlx/ { print $4 }
结果如下:
13550000000
12125656
12125656
00000000
这个脚本也可以用条件语句实现如下:
{
if ( $2 ~ /zlx/ ) {
print $4
}
}
这两个脚本的功能完全一样。第一个示例中,布尔表达式放在代码块外面。而在第二个示例中,将对每一个输入行执行代码块,而且我们使用 if 语句来选择执行 print 命令。这两个方法都可以使用。
awk 还允许使用布尔运算符 "||"(逻辑与)和 "&&"(逻辑或),以便创建更复杂的布尔表达式:
( $2 !~ /zlx/ ) && ( $3== "male" ) { print }
这个示例只打印第二个字段不包括zlx且第三个字段等于male的那些行,结果为:
1:abc:male:13612345678
6:david:male:10101010
好了,今天就讲到这儿,下篇文章开始讲解awk中的变量。