Unix awk 使用手册[2]

[入库:2005年8月19日] [更新:2007年3月24日]

本文简介:选择自 willhunt 的 blog

awk的语法:

与其它unix命令一样,awk拥有自己的语法:

awk [ -f re] [parameter...] ['prog'] [-f progfile][in_file...]

参数说明:

-f re:允许awk更改其字段分隔符。

parameter: 该参数帮助为不同的变量赋值。

'prog': awk的程序语句段。这个语句段必须用单拓号:'和'括起,以防被shell解释。这个程序语句段的标准形式为:

'pattern {action}'

其中pattern参数可以是egrep正则表达式中的任何一个,它可以使用语法/re/再加上一些样式匹配技巧构成。与sed类似,你也可以使用","分开两样式以选择某个范围。关于匹配的细节,你可以参考附录,如果仍不懂的话,找本unix书学学grep和sed(本人是在学习ed时掌握匹配技术的)。action参数总是被大括号包围,它由一系统awk语句组成,各语句之间用";"分隔。awk解释它们,并在pattern给定的样式匹配的记录上执行其操作。与shell类似,你也可以使用“#”作为注释符,它使“#”到行尾的内容成为注释,在解释执行时,它们将被忽略。你可以省略pattern和action之一,但不能两者同时省略,当省略pattern时没有样式匹配,表示对所有行(记录)均执行操作,省略action时执行缺省的操作——在标准输出上显示。

-f progfile:允许awk调用并执行progfile指定有程序文件。progfile是一个文本文件,他必须符合awk的语法。

in_file:awk的输入文件,awk允许对多个输入文件进行处理。值得注意的是awk不修改输入文件。如果未指定输入文件,awk将接受标准输入,并将结果显示在标准输出上。awk支持输入输出重定向。

awk的记录、字段与内置变量:

前面说过,awk处理的工作与数据库的处理方式有相同之处,其相同处之一就是awk支持对记录和字段的处理,其中对字段的处理是grep和sed不能实现的,这也是awk优于二者的原因之一。在awk中,缺省的情况下总是将文本文件中的一行视为一个记录,而将一行中的某一部分作为记录中的一个字段。为了操作这些不同的字段,awk借用shell的方法,用$1,$2,$3...这样的方式来顺序地表示行(记录)中的不同字段。特殊地,awk用$0表示整个行(记录)。不同的字段之间是用称作分隔符的字符分隔开的。系统默认的分隔符是空格。awk允许在命令行中用-f re的形式来改变这个分隔符。事实上,awk用一个内置的变量fs来记忆这个分隔符。awk中有好几个这样的内置变量,例如,记录分隔符变量rs、当前工作的记录数nr等等,本文后面的附表列出了全部的内置变量。这些内置的变量可以在awk程序中引用或修改,例如,你可以利用nr变量在模式匹配中指定工作范围,也可以通过修改记录分隔符rs让一个特殊字符而不是换行符作为记录的分隔符。

例:显示文本文件myfile中第七行到第十五行中以字符%分隔的第一字段,第三字段和第七字段:

awk -f % 'nr==7,nr==15 {printf $1 $3 $7}'

awk的内置函数

awk之所以成为一种优秀的程序设计语言的原因之一是它吸收了某些优秀的程序设计语言(例如c)语言的许多优点。这些优点之一就是内置函数的使用,awk定义并支持了一系列的内置函数,由于这些函数的使用,使得awk提供的功能更为完善和强大,例如,awk使用了一系列的字符串处理内置函数(这些函数看起来与c语言的字符串处理函数相似,其使用方式与c语言中的函数也相差无几),正是由于这些内置函数的使用,使awk处理字符串的功能更加强大。本文后面的附录中列有一般的awk所提供的内置函数,这些内置函数也许与你的awk版本有些出入,因此,在使用之前,最好参考一下你的系统中的联机帮助。

作为内置函数的一个例子,我们将在这里介绍awk的printf函数,这个函数使得awk与c语言的输出相一致。实际上,awk中有许多引用形式都是从c语言借用过来的。如果你熟悉c语言,你也许会记得其中的printf函数,它提供的强大格式输出功能曾经带我们许多的方便。幸运的是,我们在awk中又和它重逢了。awk中printf几乎与c语言中一模一样,如果你熟悉c语言的话,你完全可以照c语言的模式使用awk中的printf。因此在这里,我们只给出一个例子,如果你不熟悉的话,请随便找一本c语言的入门书翻翻。

例:显示文件myfile中的行号和第3字段:

$awk '{printf"%03d%s\n",nr,$1}' myfile

在命令行使用awk

按照顺序,我们应当讲解awk程序设计的内容了,但在讲解之前,我们将用一些例子来对前面的知识进行回顾,这些例子都是在命令行中使用的,由此我们可以知道在命令行中使用awk是多么的方便。这样做的原因一方面是为下面的内容作铺垫,另一方面是介绍一些解决简单问题的方法,我们完全没有必要用复杂的方法来解决简单的问题----既然awk提供了较为简单的方法的话。

例:显示文本文件mydoc匹配(含有)字符串"sun"的所有行。

$awk '/sun/{print}' mydoc

由于显示整个记录(全行)是awk的缺省动作,因此可以省略action项。

$awk '/sun/' mydoc

例:下面是一个较为复杂的匹配的示例:

$awk '/[ss]un/,/[mm]oon/ {print}' myfile

它将显示第一个匹配sun或sun的行与第一个匹配moon或moon的行之间的行,并显示到标准输出上。

例:下面的示例显示了内置变量和内置函数length()的使用:

$awk 'length($0)>80 {print nr}' myfile

该命令行将显示文本myfile中所有超过80个字符的行号,在这里,用$0表示整个记录(行),同时,内置变量nr不使用标志符'$'。

例:作为一个较为实际的例子,我们假设要对unix中的用户进行安全性检查,方法是考察/etc下的passwd文件,检查其中的passwd字段(第二字段)是否为"*",如不为"*",则表示该用户没有设置密码,显示出这些用户名(第一字段)。我们可以用如下语句实现:

#awk -f: '$2=="" {printf("%s no password!\n",$1' /etc/passwd

在这个示例中,passwd文件的字段分隔符是“:”,因此,必须用-f:来更改默认的字段分隔符,这个示例中也涉及到了内置函数printf的使用。

awk的变量

如同其它程序设计语言一样,awk允许在程序语言中设置变量,事实上,提供变量的功能是程序设计语言的其本要求,不提供变量的程序设计语言本人还从未见过。

awk提供两种变量,一种是awk内置的变量,这前面我们已经讲过,需要着重指出的是,与后面提到的其它变量不同的是,在awk程序中引用内置变量不需要使用标志符"$"(回忆一下前面讲过的nr的使用)。awk提供的另一种变量是自定义变量。awk允许用户在awk程序语句中定义并调用自已的变量。当然这种变量不能与内置变量及其它awk保留字相同,在awk中引用自定义变量必须在它前面加上标志符"$"。与c语言不同的是,awk中不需要对变量进行初始化,awk根据其在awk中第一次出现的形式和上下文确定其具体的数据类型。当变量类型不确定时,awk默认其为字符串类型。这里有一个技巧:如果你要让你的awk程序知道你所使用的变量的明确类型,你应当在在程序中给它赋初值。在后面的实例中,我们将用到这一技巧。

运算与判断:

作为一种程序设计语言所应具有的特点之一,awk支持多种运算,这些运算与c语言提供的几本相同:如+、-、*、/、%等等,同时,awk也支持c语言中类似++、--、+=、-=、=+、=-之类的功能,这给熟悉c语言的使用者编写awk程序带来了极大的方便。作为对运算功能的一种扩展,awk还提供了一系列内置的运算函数(如log、sqr、cos、sin等等)和一些用于对字符串进行操作(运算)的函数(如length、substr等等)。这些函数的引用大大的提高了awk的运算功能。

作为对条件转移指令的一部分,关系判断是每种程序设计语言都具备的功能,awk也不例外。awk中允许进行多种测试,如常用的==(等于)、!=(不等于)、>(大于)、<(小于)、>=(大于等于)、>=(小于等于)等等,同时,作为样式匹配,还提供了~(匹配于)和!~(不匹配于)判断。

作为对测试的一种扩充,awk也支持用逻辑运算符:!(非)、&&(与)、||(或)和括号()进行多重判断,这大大增强了awk的功能。本文的附录中列出了awk所允许的运算、判断以及操作符的优先级。

awk的流程控制

流程控制语句是任何程序设计语言都不能缺少的部分。任何好的语言都有一些执行流程控制的语句。awk提供的完备的流程控制语句类似于c语言,这给我们编程带来了极大的方便。

1、begin和end:

在awk中两个特别的表达式,begin和end,这两者都可用于pattern中(参考前面的awk语法),提供begin和end的作用是给程序赋予初始状态和在程序结束之后执行一些扫尾的工作。任何在begin之后列出的操作(在{}内)将在awk开始扫描输入之前执行,而end之后列出的操作将在扫描完全部的输入之后执行。因此,通常使用begin来显示变量和预置(初始化)变量,使用end来输出最终结果。

例:累计销售文件xs中的销售金额(假设销售金额在记录的第三字段):

$awk
>'begin { fs=":";print "统计销售金额";total=0}
>{print $3;total=total+$3;}
>end {printf "销售金额总计:%.2f",total}' sx
(注:>是shell提供的第二提示符,如要在shell程序awk语句和awk语言中换行,则需在行尾加反斜杠\)

在这里,begin预置了内部变量fs(字段分隔符)和自定义变量total,同时在扫描之前显示出输出行头。而end则在扫描完成后打印出总合计。

2、流程控制语句
awk提供了完备的流程控制语句,其用法与c语言类似。下面我们一一加以说明:

2.1、if...else语句:

格式:
if(表达式)
语句1
else
语句2

本文关键:awk unix
  相关方案
Google
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top