flymeteor@Blog



awk使用手册

什么是awk?

ä½ å?¯èƒ½å¯¹UNIX比较熟悉,但你å?¯èƒ½å¯¹awk很陌生,这一点也ä¸?奇怪,的确,与其优秀的功能相比,awk还远没达到它应有的知å??度。awk是什么?与其它大多数UNIX命令ä¸?å?Œçš„æ˜¯ï¼Œä»Žå??字上看,我们ä¸?å?¯èƒ½çŸ¥é?“awk的功能:它既ä¸?是具有独立æ„?义的英文å?•è¯?,也ä¸?是几个相关å?•è¯?的缩写。事实上,awk是三个人å??的缩写,他们是:Ahoã€?(Peter)Weinbergå’Œ (Brain)Kernighan。正是这三个人创造了awk—一个优秀的样å¼?扫æ??与处ç?†å·¥å…·ã€‚

AWK的功能是什么?与sedå’Œ grep很相似,awk是一ç§?æ ·å¼?扫æ??与处ç?†å·¥å…·ã€‚但其功能å?´å¤§å¤§å¼ºäºŽsedå’Œgrep。awkæ??供了æž?其强大的功能:它几乎å?¯ä»¥å®Œæˆ?grepå’Œsed所能完æˆ?的全部工作,å?Œæ—¶ï¼Œå®ƒè¿˜å?¯ä»¥å?¯ä»¥è¿›è¡Œæ ·å¼?装入ã€?æµ?控制ã€?æ•°å­¦è¿?算符ã€?进程控制语å?¥ç”šè‡³äºŽå†…置的å?˜é‡?和函数。它具备了一个完整的语言所应具有的几乎所有精美特性。实际上,awk的确拥有自己的语言:awk程åº?设计语言,awk的三ä½?创建者已将它正å¼?定义为:样å¼?扫æ??和处ç?†è¯­è¨€ã€‚

为什么使用awk?

�使如此,你也许�然会问,我为什么�使用awk?

使用awk的第一个ç?†ç”±æ˜¯åŸºäºŽæ–‡æœ¬çš„æ ·å¼?扫æ??和处ç?†æ˜¯æˆ‘们ç»?常å?šçš„工作,awk所å?šçš„工作有些象数æ?®åº“,但与数æ?®åº“ä¸?å?Œçš„æ˜¯ï¼Œå®ƒå¤„ç?†çš„æ˜¯æ–‡æœ¬æ–‡ä»¶ï¼Œè¿™äº›æ–‡ä»¶æ²¡æœ‰ä¸“门的存储格å¼?,普通的人们就能编辑ã€?阅读ã€?ç?†è§£å’Œå¤„ç?†å®ƒä»¬ã€‚而数æ?®åº“文件往往具有特殊的存储格å¼?,这使得它们必须用数æ?®åº“处ç?†ç¨‹åº?æ?¥å¤„ç?†å®ƒä»¬ã€‚既然这ç§?类似于数æ?®åº“的处ç?†å·¥ä½œæˆ‘们ç»?常会é?‡åˆ°ï¼Œæˆ‘们就应当找到处ç?†å®ƒä»¬çš„简便易行的方法,UNIX有很多这方é?¢çš„工具,例如sed ã€?grepã€?sort以å?Šfind等等,awk是其中å??分优秀的一ç§?。

使用awk的第二个ç?†ç”±æ˜¯awk是一个简å?•的工具,当然这是相对于其强大的功能æ?¥è¯´çš„。的确,UNIX有许多优秀的工具,例如UNIX天然的开å?‘工具C语言å?Šå…¶å»¶ç»­C++å°±é?žå¸¸çš„优秀。但相对于它们æ?¥è¯´ï¼Œawk完æˆ?å?Œæ ·çš„功能è¦?方便和简æ?·å¾—多。这首先是因为awkæ??供了适应多ç§?需è¦?的解决方案:从解决简å?•问题的awk命令行到å¤?æ?‚而精巧的awk程åº?设计语言,这样å?šçš„好处是,你å?¯ä»¥ä¸?必用å¤?æ?‚的方法去解决本æ?¥å¾ˆç®€å?•的问题。例如,你å?¯ä»¥ç”¨ä¸€ä¸ªå‘½ä»¤è¡Œè§£å†³ç®€å?•的问题,而Cä¸?行,å?³ä½¿ä¸€ä¸ªå†?简å?•的程åº?,C语言也必须ç»?过编写ã€?编译的全过程。其次,awk本身是解释执行的,这就使得awk程åº?ä¸?å¿…ç»?过编译的过程,å?Œæ—¶ï¼Œè¿™ä¹Ÿä½¿å¾—它与shell script程åº?能够很好的契å?ˆã€‚最å?Žï¼Œawk本身较C语言简å?•,虽然awkå?¸æ”¶äº†C语言很多优秀的æˆ?分,熟悉C语言会对学习awk有很大的帮助,但 awk本身ä¸?é¡»è¦?会使用C语言——一ç§?功能强大但需è¦?大é‡?时间学习æ‰?能掌æ?¡å…¶æŠ€å·§çš„å¼€å?‘工具。

使用awk的第三个ç?†ç”±æ˜¯awk是一个容易获得的工具。与Cå’ŒC++语言ä¸?å?Œï¼Œawkå?ªæœ‰ä¸€ä¸ªæ–‡ä»¶(/bin/awk),而且几乎æ¯?个版本的UNIX都æ??ä¾›å?„自版本的awk,你完全ä¸?必费心去想如何获得awk。但C语言å?´ä¸?是这样,虽然C语言是UNIX天然的开å?‘工具,但这个开å?‘工具å?´æ˜¯å?•独å?‘行的,æ?¢è¨€ä¹‹ï¼Œä½ å¿…须为你的UNIX版本的C语言开å?‘工具å?•独付费(当然使用D版者除外),获得并安装它,然å?Žä½ æ‰?å?¯ä»¥ä½¿ç”¨å®ƒã€‚

基于以上ç?†ç”±ï¼Œå†?加上awk强大的功能,我们有ç?†ç”±è¯´ï¼Œå¦‚果你è¦?处ç?†ä¸Žæ–‡æœ¬æ ·å¼?扫æ??相关的工作,awk应该是你的第一选择。在这里有一个å?¯é?µå¾ªçš„一般原则:如果你用普通的shell工具或shell script有困难的è¯?,试试awk,如果awkä»?ä¸?能解决问题,则便用C语言,如果C语言ä»?然失败,则移至C++。

awk的调用方�

å‰?é?¢æ›¾ç»?说过,awkæ??供了适应多ç§?需è¦?çš„ä¸?å?Œè§£å†³æ–¹æ¡ˆï¼Œå®ƒä»¬æ˜¯ï¼š

一� awk命令行,你�以象使用普通UNIX命令一样使用awk,在命令行中你也�以使用awk程�设计语言,虽然awk支�多行的录入,但是录入长长的命令行并��其正确无误�是一件令人头疼的事,因此,这�方法一般�用于解决简�的问题。当然,你也�以在shell script程�中引用awk命令行甚至awk程�脚本。

二�使用-f选项调用awk程�。awk�许将一段awk程�写入一个文本文件,然�在awk命令行中用-f选项调用并执行这段程�。具体的方法我们将在��的awk语法中讲到。

三�利用命令解释器调用awk程�:利用UNIX支�的命令解释器功能,我们�以将一段awk程�写入文本文件,然�在它的第一行加上:
#!/bin/awk -f
并赋予这个文本文件以执行的��。这样�之�,你就�以在命令行中用类似于下�这样的方�调用并执行这段awk程�了。

$awk脚本文本å?? 待处ç?†æ–‡ä»¶

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

æ ¼å¼?中”语å?¥1″å?¯ä»¥æ˜¯å¤šä¸ªè¯­å?¥ï¼Œå¦‚果你为了方便awk判断也方便你自已阅读,你最好将多个语å?¥ç”¨{}括起æ?¥ã€‚awk分æž?结构å…?许嵌套,其格å¼?为:

if(表达�1)
{if(表达�2)
语�1
else
语�2
}
语�3
else {if(表达�3)
语�4
else
语�5
}
语�6

当然实际�作过程中你�能�会用到如此��的分�结构,这里�是为了给出其样�罢了。

2.2�while语�

格�为:

while(表达�)
语�

2.3�do-while语�

格�为:

do
{
语�
}while(�件判断语�)

2.4�for语�

格�为:

for(�始表达�;终止�件;步长表达�)
{语�}

在awk 的 while�do-while和for语�中�许使用break,continue语��控制�程走�,也�许使用exit这样的语��退出。break 中断当�正在执行的循环并跳到循环外执行下一�语�。continue从当��置跳到循环开始处执行。对于exit的执行有两�情况:当exit语��在 END中时,任何�作中的exit命令表现得如�到了文件尾,所有模�或�作执行将�止,END模�中的�作被执行。而出现在END中的exit将导致程�终止。

例:为了

awk中的自定义函数

定义和调用用户自己的函数是几乎æ¯?个高级语言都具有的功能,awk也ä¸?例外,但原始的awkå¹¶ä¸?æ??供函数功能,å?ªæœ‰åœ¨nawk或较新的awk版本中æ‰?å?¯ä»¥å¢žåŠ å‡½æ•°ã€‚

函数的使用包�两部分:函数的定义与函数调用。其中函数定义�包括�执行的代�(函数本身)和从主程�代�传递到该函数的临时调用。

awk函数的定义方法如下:

function 函数å??(å?‚数表){
函数体
}

在gawk中å…?许将functionçœ?略为func,但其它版本的awkä¸?å…?许。函数å??必须是一个å?ˆæ³•的标志符,å?‚数表中å?¯ä»¥ä¸?æ??ä¾›å?‚数(但在调用函数时函数å??å?Žçš„一对括å?·ä»?然是ä¸?å?¯ç¼ºå°‘的),也å?¯ä»¥æ??供一个或多个å?‚数。与C语言相似,awkçš„å?‚数也是通过值æ?¥ä¼ é€’的。

在awk 中调用函数比较简�,其方法与C语言相似,但awk比C语言更为�活,它�执行�数有效性检查。���说,在你调用函数时,�以列出比函数预计(函数定义中规定)的多或少的�数,多余的�数会被awk所忽略,而�足的�数,awk将它们置为缺�值0或空字符串,具体置为何值,将�决于�数的使用方�。

awk函数有两ç§?返回方å¼?:éš?å¼?返回和显å¼?返回。当awk执行到函数的结尾时,它自动地返回到调用程åº?,这是函数是éš?å¼?返回的。如果需è¦?在结æ?Ÿä¹‹å‰?退出函数,å?¯ä»¥æ˜Žç¡®åœ°ä½¿ç”¨è¿”回语å?¥æ??å‰?退出。方法是在函数中使用形如:return 返回值 æ ¼å¼?的语å?¥ã€‚

例:下é?¢çš„例å­?演示了函数的使用。在这个示例中,定义了一个å??为print_header的函数,该函数调用了两个å?‚æ•°FileNameå’ŒPageNum, FileNameå?‚数传给函数当å‰?使用的文件å??,PageNumå?‚数是当å‰?页的页å?·ã€‚这个函数的功能是打å?°ï¼ˆæ˜¾ç¤ºï¼‰å‡ºå½“å‰?文件的文件å??,和当å‰?页的页å?·ã€‚完æˆ?这个功能å?Žï¼Œè¿™ä¸ªå‡½æ•°å°†è¿”回下一页的页å?·ã€‚

nawk
>’BEGIN{pageno=1;file=FILENAME
>pageno=print_header(file,pageno);#调用函数print_header
>printf(“当å‰?页页å?·æ˜¯ï¼š%d\n”,pageno);
>}

>#定义函数print_header
>function print_header(FileName,PageNum){
>printf(“%s %d\n”,FileName,PageNum); >PageNum++;return PageNUm;
>}
>}’ myfile

执行这个程�将显示如下内容:

myfile 1
当�页页�是:2

awk高级输入输出

1.读�下一�记录:

awk的next语�导致awk读�下一个记录并完�模�匹�,然�立�执行相应的�作。通常它用匹�的模�执行�作中的代�。next导致这个记录的任何�外匹�模�被忽略。

2.简�地读�一�记录

awk 的 getline语�用于简�地读�一�记录。如果用户有一个数�记录类似两个物�记录,那么getline将尤其有用。它完�一般字段的分离(设置字段��$0 FNR NF NR)。如果�功则返回1,失败则返回0(到达文件尾)。如果需简�地读�一个文件,则�以编写以下代�:

例:示例getline的使用

{while(getline==1)
{
#process the inputted fields
}
}

也�以使getline�存输入数�在一个字段中,而�是通过使用getline variable的形�处�一般字段。当使用这�方�时,NF被置�0,FNR和NR被增值。

用户也å?¯ä»¥ä½¿ç”¨getline”datafile”
或
printf(“hello word!\n”)>>”datafile”

5.输出到一个命令

awk中�许用如下方�将结果输出到一个命令:

printf(“hello word!\n”)|”sort-t’,'”

awk与shell script混�编程

因为awkå?¯ä»¥ä½œä¸ºä¸€ä¸ªshell命令使用,因此awk能与shell批处ç?†ç¨‹åº?很好的èž?å?ˆåœ¨ä¸€èµ·ï¼Œè¿™ç»™å®žçްawk与shell程åº?的混å?ˆç¼–程æ??供了å?¯èƒ½ã€‚实现混å?ˆç¼–程的关键是awk与shell script之间的对è¯?,æ?¢è¨€ä¹‹ï¼Œå°±æ˜¯awk与shell script之间的信æ?¯äº¤æµ?:awk从shell script中获å?–所需的信æ?¯ï¼ˆé€šå¸¸æ˜¯å?˜é‡?的值)ã€?在awk中执行shell命令行ã€?shell script将命令执行的结果é€?ç»™awk处ç?†ä»¥å?Šshell script读å?–awk的执行结果等等。

1.awk读�Shell script程���

在awk中我们å?¯ä»¥é€šè¿‡â€œ’$å?˜é‡?å??’â€?的方å¼?读å?–sell scrpit程åº?中的å?˜é‡?。

例:在下é?¢çš„示例中,我们将读å?–sell scrpit程åº?中的å?˜é‡?Name,该å?˜é‡?存放的是文本myfile的撰写者,awk将打å?°å‡ºè¿™ä¸ªäººå??。

$cat writename
:
# @(#)
#
.
.
.
Name=”张三” nawk ‘BEGIN {name=”‘Name’”;\ printf(“\t%s\t撰写者%s\n”,FILENAME,name”);}\
{…}END{…}’ myfile
.
.
.

2.将shell命令的执行结果�给awk处�

作为信�传�的一�方法,我们�以将一�shell命令的结果通过管�线(|)传递给awk处�:

例:示例awk处�shell命令的执行结果

$who -u | awk ‘{printf(“%s正在执行%s\n”,$2,$1)}’

该命令将打å?°å‡ºæ³¨å†Œç»ˆç«¯æ­£åœ¨æ‰§è¡Œçš„程åº?å??。

3.shell script程�读awk的执行结果

为了实现shell script程åº?读å?–awk执行的结果,我们å?¯ä»¥é‡‡å?–一些特殊的方法,例如我们å?¯ä»¥ç”¨å?˜é‡?å??=`awk语å?¥`的形å¼?å°†awk执行的结果存放入一个 shell scriptå?˜é‡?。当然也å?¯ä»¥ç”¨ç®¡é?“线的方法将awk执行结果传递给shell script程åº?处ç?†ã€‚

例:作为传é€?消æ?¯çš„æœºåˆ¶ä¹‹ä¸€ï¼ŒUNIXæ??供了一个å?‘其所有用户传é€?消æ?¯çš„命令wall(æ„?æ€?是write to all写给所有用户),该命令å…?许å?‘所有工作中的用户(终端)å?‘é€?消æ?¯ã€‚为此,我们å?¯ä»¥é€šè¿‡ä¸€æ®µshell批处ç?†ç¨‹åº?wall.shellæ?¥æ¨¡æ‹Ÿè¿™ä¸€ç¨‹åº?(事实上比较è€?的版本中wall就是一段shell批处ç?†ç¨‹åº?:

$cat wall.shell
:
# @(#) wall.shell:��消�给�个已注册终端
#
cat >/tmp/$$
#用户录入消æ?¯æ–‡æœ¬ who -u | awk ‘{print $2}’ | while read tty
do
cat /tmp/$$>$tty
done

在这个程åº?里,awk接å?—who -u命令的执行结果,该命令打å?°å‡ºæ‰€æœ‰å·²æ³¨å†Œç»ˆç«¯çš„ä¿¡æ?¯ï¼Œå…¶ä¸­ç¬¬äºŒä¸ªå­—段是已注册终端的设备å??,因此用awk命令æž?出该设备å??,然å?Žç”¨while read tty语å?¥å¾ªçŽ¯è¯»å‡ºè¿™äº›æ–‡ä»¶å??到å?˜é‡?(shell scriptå?˜é‡?)tty中,作为信æ?¯ä¼ é€?的终结地å?€ã€‚

4.在awk中执行shell命令行—-嵌入函数system()

system()是一个�适�字符或数字类型的嵌入函数,该函数的功能是处�作为�数传递给它的字符串。system对这个�数的处�就是将其作为命令处�,也就是说将其当作命令行一样加以执行。这使得用户在自己的awk程�需�时�以�活地执行命令或脚本。

例:下é?¢çš„程åº?将使用system嵌入函数打å?°ç”¨æˆ·ç¼–制好的报表文件,这个文件存放在å??为myreport.txt的文件中。为简约起è§?,我们å?ªåˆ—出了其END部分:

.
.
.
END {close(“myreport.txt”);system(“lp myreport.txt”);}

在这个示例中,我们首先使用close语�关闭了文件myreport.txt文件,然�使用system嵌入函数将myreport.txt�入打�机打�。

写到这里,我�得�跟朋�们说��了,实在地说,这些内容�然是awk的�步知识,电脑永远是�进的科学,awk也�例外,本篇所能�的�是在你�行的漫漫长途中铺平一段��开端,剩下的路还得�你自己去走。�实说,如果本文真能给你�行的路上带�些许的方便,那本人就知足了�

如对本篇有任何疑问,请E-mail To:Chizlong@yeah.net或到主页http://chizling.yeah.net中留言。

附录:

1.awk的常规表达�元字符

\ ���列
^ 在字符串的开头开始匹�
$ 在字符串的结尾开始匹�
. 与任何�个字符串匹�
[ABC] 与[]内的任一字符匹�
[A-Ca-c] 与A-C�a-c范围内的字符匹�(按字�表顺�)
[^ABC] 与除[]内的所有字符以外的任一字符匹�
Desk|Chair 与Desk和Chair中的任一个匹�
[ABC][DEF] 关�。与A�B�C中的任一字符匹�,且其��跟D�E�F中的任一个字符。
* 与A�B或C中任一个出现0次或多次的字符相匹�
+ 与A�B或C中任何一个出现1次或多次的字符相匹�
? 与一个空串或A�B或C在任何一个字符相匹�
(Blue|Black)berry �并常规表达�,与Blueberry或Blackberry相匹�

2.awk算术�算符

�算符 用途
——————
x^y x的y次幂
x**y �上
x%y 计算x/y的余数(求模)
x+y x加y
x-y x�y
x*y x乘y
x/y x除y
-y 负y(y的开关符�);也称一目�
++y y加1�使用y(�置加)
y++ 使用y值�加1(�缀加)
–y yå‡?1å?Žä½¿ç”¨y(å‰?ç½®å‡?)
y– 使用å?Žyå‡?1(å?Žç¼€å‡?)
x=y 将y的值赋给x
x+=y 将x+y的值赋给x
x-=y 将x-y的值赋给x
x*=y 将x*y的值赋给x
x/=y 将x/y的值赋给x x%=y 将x%y的值赋给x
x^=y 将x^y的值赋给x
x**=y 将x**y的值赋给x

3.awk�许的测试:

�作符 �义

x==y x等于y
x!=y x�等于y
x>y x大于y
x>=y x大于或等于y
x >=




Leave a Comment

(required)

(required)



Formatting your comment
Back to Top | Textarea: Larger | Smaller