为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

awk使用手册

2013-10-24 29页 pdf 108KB 28阅读

用户头像

is_807242

暂无简介

举报
awk使用手册 Unix awk使用手册 作者:莫名 发表时间:2002/01/27 01:39pm 什么是 awk? 你可能对 UNIX比较熟悉,但你可能对 awk很陌生,这一点也不奇怪,的确,与其优秀 的功能相比,awk还远没达到它应有的知名度。awk是什么?与其它大多数 UNIX命令 不同的是,从名字上看,我们不可能知道 awk的功能:它既不是具有独立意义的英文单 词,也不是几个相关单词的缩写。事实上,awk 是三个人名的缩写,他们是:Aho、 (Peter)Weinberg和(Brain)Kernighan。正是这三...
awk使用手册
Unix awk使用手册 作者:莫名 发时间:2002/01/27 01:39pm 什么是 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<"filename"方式从一个给定的文件中输入数据,而不是从命令行 所列内容输入数据。此时,getline将完成一般字段分离(设置字段变量$0和 NF)。如果 文件不存在,返回-1,成功,返回 1,返回 0表示失败。用户可以从给定文件中读取数据到 一个变量中,也可以用 stdin(标准输入设备)或一个包含这个文件名的变量代替 filename。 值得注意的是当使用这种方式时不修改 FNR和 NR。 另一种使用 getline语句的方法是从 UNIX命令接受输入,例如下面的例子: 例:示例从 UNIX命令接受输入 {while("who -u"|getline) { #process each line from the who command } } 当然,也可以使用如下形式: "command" | getline variable 3.关闭文件: awk中允许在程序中关闭一个输入或输出文件,方法是使用 awk的 close语句。 close("filename") filename可以是 getline打开的文件(也可以是 stdin,包含文件名的变量或者 getline使用 的确切命令)。或一个输出文件(可以是 stdout,包含文件名的变量或使用管道的确切命 令)。 4.输出到一个文件: awk中允许用如下方式将结果输出到一个文件: printf("hello word!\n")>"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中我们可以通过“'$变量名'”的方式读取 shell scrpit程序中的变量。 例:在下面的示例中,我们将读取 shell 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中的任一个字符。 [ABC]* 与 A、B或 C中任一个出现 0次或多次的字符相匹配 [ABC]+ 与 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 >= < <= == != ~ !~ xy (字符串连结,'x''y'变成"xy") + - * / % ++ -- 5.awk内置变量(预定义变量) 说明:表中 v 项表示第一个支持变量的工具(下同):A=awk,N=nawk,P=POSIX awk,G=gawk V 变量 含义 缺省值 ------------------------------------------------------------------ N ARGC 命令行参数个数 G ARGIND 当前被处理文件的 ARGV标志符 N ARGV 命令行参数数组 G CONVFMT 数字转换格式 %.6g P ENVIRON UNIX 环境变量 N ERRNO UNIX 系统错误消息 G FIELDWIDTHS 输入字段宽度的空白分隔字符串 A FILENAME 当前输入文件的名字 P FNR 当前记录数 A FS 输入字段分隔符 空格 G IGNORECASE 控制大小写敏感 0(大小写敏感) A NF 当前记录中的字段个数 A NR 已经读出的记录数 A OFMT 数字的输出格式 %.6g A OFS 输出字段分隔符 空格 A ORS 输出的记录分隔符 新行 A RS 输入的记录他隔符 新行 N RSTART 被匹配函数匹配的字符串首 N RLENGTH 被匹配函数匹配的字符串长度 N SUBSEP 下标分隔符 "\034" 6.awk的内置函数 V 函数 用途或返回值 --------------------------------------------------------------------- N gsub(reg,string,target) 每次常规表达式 reg匹配时替换 target中的 string N index(search,string) 返回 string中 search串的位置 A length(string) 求串 string中的字符个数 N match(string,reg) 返回常规表达式 reg匹配的 string中的位置 N printf(format,variable) 格式化输出,按 format提供的格式输出变量 variable。 N split(string,store,delim) 根据分界符 delim,分解 string为 store的数组元素 N sprintf(format,variable) 返回一个包含基于 format的格式化数据, variables是要放到串中的数据 G strftime(format,timestamp) 返 回 一 个 基 于 format 的 日 期 或 者 时 间 串 , timestmp是 systime()函数返回的时间 N sub(reg,string,target) 第一次当常规表达式 reg匹配,替换 target串中的字符串 A substr(string,position,len) 返回一个以 position开始 len个字符的子串 P tolower(string) 返回 string中对应的小写字符 P toupper(string) 返回 string中对应的大写字符 A atan(x,y) x的余切(弧度) N cos(x) x的余弦(弧度) A exp(x) e的 x幂 A int(x) x的整数部分 A log(x) x的自然对数值 N rand() 0-1之间的随机数 N sin(x) x的正弦(弧度) A sqrt(x) x的平方根 A srand(x) 初始化随机数发生器。如果忽略 x,则使用 system() G system() 返回自 1970年 1月 1日以来经过的时间(按秒计算) ************************************************************************* 通用线程:Awk 实例 作者:donggua1 发表时间:2002/08/29 08:24am 通用线程:Awk 实例 Daniel Robbins (drobbins@gentoo.org) 第一部分 Awk 是一种非常好的语言,同时有一个非常奇怪的名称。在本系列(共三篇文章)的 第一篇文章中,Daniel Robbins 将使您迅速掌握 awk 编程技巧。随着本系列的进展, 将讨论更高级的主题,最后将演示一个真正的高级 awk 演示程序。 捍卫 awk 在本系列文章中,我将使您成为精通 awk 的编码人员。我承认,awk 并没有一个非常 好听且又非常“时髦”的名字。awk 的 GNU 版本(叫作 gawk)听起来非常怪异。那 些不熟悉这种语言的人可能听说过"awk",并可能认为它是一组落伍且过时的混乱代码。 它甚至会使最博学的 UNIX 权威陷于错乱的边缘(使他不断地发出 "kill -9!" 命令,就 象使用咖啡机一样)。 的确,awk 没有一个动听的名字。但它是一种很棒的语言。awk 适合于文本处理和报 表生成,它还有许多精心设计的特性,允许进行需要特殊技巧程序设计。与某些语言不 同,awk 的语法较为常见。它借鉴了某些语言的一些精华部分,如 C 语言、python 和 bash(虽然在技术上,awk 比 python 和 bash 早创建)。awk 是那种一旦学会了就会成 为您战略编码库的主要部分的语言。 第一个 awk 让我们继续,开始使用 awk,以了解其工作原理。在命令行中输入以下命令: $ awk '{ print }' /etc/passwd 您将会见到 /etc/passwd 文件的内容出现在眼前。现在,解释 awk 做了些什么。调用 awk 时,我们指定/etc/passwd 作为输入文件。执行 awk 时,它依次对 /etc/passwd 中 的每一行执行 print 命令。所有输出都发送到 stdout,所得到的结果与与执行 catting /etc/passwd完全相同。 现在,解释 { print } 代码块。在 awk 中,花括号用于将几块代码组合到一起,这一点 类似于 C 语言。在代码块中只有一条 print 命令。在 awk 中,如果只出现 print 命令, 那么将打印当前行的全部内容。 这里是另一个 awk 示例,它的作用与上例完全相同: $ awk '{ print $0 }' /etc/passwd 在 awk 中,$0 变量表示整个当前行,所以 print 和 print $0 的作用完全一样。 如果您愿意,可以创建一个 awk 程序,让它输出与输入数据完全无关的数据。以下是 一个示例: $ awk '{ print "" }' /etc/passwd只要将 "" 字符串传递给 print 命令,它就会打印空白行。 如果测试该脚本,将会发现对于/etc/passwd文件中的每一行,awk 都输出一个空白行。 再次说明, awk 对输入文件中的每一行都执行这个脚本。以下是另一个示例: $ awk '{ print "hiya" }' /etc/passwd 运行这个脚本将在您的屏幕上写满 hiya。:) 多个字段 awk 非常善于处理分成多个逻辑字段的文本,而且让您可以毫不费力地引用 awk 脚本 中每个独立的字段。以下脚本将打印出您的系统上所有用户帐户的列表: $ awk -F":" '{ print $1 }' /etc/passwd 上例中,在调用 awk 时,使用 -F 选项来指定 ":" 作为字段分隔符。awk 处理 print $1 命令时,它会打印出在输入文件中每一行中出现的第一个字段。以下是另一个示例 $ awk -F":" '{ print $1 $3 }' /etc/passwd 以下是该脚本输出的摘录 halt7operator11root0shutdown6sync5bin1....etc. 如您所见,awk 打印出 /etc/passwd 文件的第一和第三个字段,它们正好分别是用户名 和用户标识字段。现在,当脚本运行时,它并不理想 -- 在两个输出字段之间没有空格! 如果习惯于使用 bash 或 python 进行编程,那么您会指望 print $1 $3 命令在两个字段 之间插入空格。然而,当两个字符串在 awk 程序中彼此相邻时,awk 会连接它们但不 在它们之间添加空格。以下命令会在这两个字段中插入空格: $ awk -F":" '{ print $1 " " $3 }' /etc/passwd 以这种方式调用 print 时,它将连接 $1、" " 和 $3,创建可读的输出。当然,如果需 要的话,我们还可以插入一些文本标签: $ awk -F":" '{ print "username: " $1 "\t\tuid:" $3" }' /etc/passwd 这将产生以下输出: username:haltuid:7username:operatorid:11username:rootuid:0username: shutdown uid:6username: sync uid:5username: bin uid:1....etc. 外部脚本 将脚本作为命令行自变量传递给 awk 对于小的单行程序来说是非常简单的,而对于多 行程序,它就比较复杂。您肯定想要在外部文件中撰写脚本。然后可以向 awk 传递 -f 选项,以向它提供此脚本文件: $ awk -f myscript.awk myfile.in 将脚本放入文本文件还可以让您使用附加 awk 功能。例如,这个多行脚本与前面的单 行脚本的作用相同,它们都打印出 /etc/passwd 中每一行的第一个字段: BEGIN { FS=":"}{ print $1 } 这两个方法的差别在于如何设置字段分隔符。在这个脚本中,字段分隔符在代码自身中 指定(通过设置 FS 变量),而在前一个示例中,通过在命令行上向 awk 传递 -F":" 选 项来设置 FS。通常,最好在脚本自身中设置字段分隔符,只是因为这表示您可以少输 入一个命令行自变量。我们将在本文的后面详细讨论 FS 变量。 BEGIN 和 END 块 通常,对于每个输入行,awk 都会执行每个脚本代码块一次。然而,在许多编程情况中, 可能需要在 awk 开始处理输入文件中的文本之前执行初始化代码。对于这种情况,awk 允许您定义一个 BEGIN 块。我们在前一个示例中使用了 BEGIN 块。因为 awk 在开 始处理输入文件之前会执行 BEGIN 块,因此它是初始化 FS(字段分隔符)变量、打 印页眉或初始化其它在程序中以后会引用的全局变量的极佳位置。 awk 还提供了另一个特殊块,叫作 END 块。awk 在处理了输入文件中的所有行之后 执行这个块。通常,END 块用于执行最终计算或打印应该出现在输出流结尾的摘要信 息。表达式和块 awk 允许使用规则表达式,根据规则表达式是否匹配当前行来选 择执行独立代码块。以下示例脚本只输出包含字符序列 foo 的那些行: /foo/ { print } 当然,可以使用更复杂的规则表达式。以下脚本将只打印包含浮点数的行: /[0-9]+\.[0-9]*/ { print } 表达式和块还有许多其它方法可以选择执行代码块。我们可以将任意一种布尔表达式放 在一个代码块之前,以控制何时执行某特定块。仅当对前面的布尔表达式求值为真时, awk 才执行代码块。以下示例脚本输出将输出其第一个字段等于 fred 的所有行中的第 三个字段。如果当前行的第一个字段不等于 fred,awk 将继续处理文件而不对当前行执 行 print 语句: $1 == "fred" { print $3 } awk 提供了完整的比较运算符集合,包括 "=="、"<"、">"、"<="、">=" 和 "!="。另外, awk 还提供了 "~" 和 "!~" 运算符,它们分别表示“匹配”和“不匹配”。它们的用法是在运算符左边指定 变量,在右边指定规则表达式。如果某一行的第五个字段包含字符序列 root,那么以下 示例将只打印这一行中的第三个字段 : $5 ~ /root/ { print $3 } 条件语句 awk 还提供了非常好的类似于 C 语言的 if 语句。如果您愿意,可以使用 if 语句重写 前一个脚本: { if ( $5 ~ /root/ ) {print $3}} 这两个脚本的功能完全一样。第一个示例中,布尔表达式放在代码块外面。而在第二个 示例中,将对每一个输入行执行代码块,而且我们使用 if 语句来选择执行 print 命令。 这两个方法都可以使用,可以选择最适合脚本其它部分的一种方法。 以下是更复杂的 awk if 语句示例。可以看到,尽管使用了复杂、嵌套的条件语句,if 语 句看上去仍与相应的 C 语言 if 语句一样: { if ( $1 == "foo" ) {if ( $2 == "foo" ) { print "uno" } else {print "one" }} else if ($1 == "bar") {print "two"} else {print "three" }} 使用 if 语句还可以将代码: ! /matchme/ { print $1 $3 $4 } 转换成: { if ( $0 !~ /matchme/ ) { print $1 $3 $4}} 这两个脚本都只输出不包含 matchme 字符序列的那些行。此外,还可以选择最适合您 的代码的方法。它们的功能完全相同。awk 还允许使用布尔运算符 "||"(逻辑与)和 "&&" (逻辑或),以便创建更复杂的布尔表达式: ( $1 == "foo" ) && ( $2 == "bar" ) { print } 这个示例只打印第一个字段等于 foo 且第二个字段等于 bar 的那些行。 数值变量! 至今,我们不是打印字符串、整行就是特定字段。然而,awk 还允许我们执行整数和浮 点运算。通过使用数学表达式,可以很方便地编写计算文件中空白行数量的脚本。以下 就是这样一个脚本: BEGIN { x=0 }/^$/{ x=x+1 }END
/
本文档为【awk使用手册】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索