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?

即便如此,你可能还是会问c语言 脚本解释器,我为什么要使用 awk?

使用 awk 的第一个原因是基于文本的样式扫描和处理是我们经常做的事情。 awk 做一些类似于数据库的事情,但与数据库不同的是,它处理的是文本文件,没有专门的存储格式,普通人可以编辑、阅读、理解和处理它们。另一方面,数据库文件通常具有特殊的存储格式,这使得它们必须使用数据库处理程序来处理它们。由于我们经常会遇到这种类似数据库的处理工作,所以我们应该找到一种简单易行的方法来处理它们。 UNIX为此提供了很多工具,如sed、grep、sort和find等,awk就是其中之一。

使用 awk 的第二个原因是 awk 是一个简单的工具,当然相对于它的强大功能而言。确实,UNIX 有很多优秀的工具,比如 UNIX 的天然开发工具 C 语言和它的继承 C++ 非常好。但相对于它们,awk 完成同样的功能要方便和简单得多。这首先是因为 awk 为各种需求提供了解决方案:从用于解决简单问题的 awk 命令行到复杂而复杂的 awk 编程语言。简单的问题。例如,您可以使用命令行来解决简单的问题,但 C 不能。即使是一个简单的程序,C语言也必须经过编写和编译的全过程。其次,awk本身是被解释执行的,这使得awk程序不必经过编译过程,同时这也使得它与shell脚本程序非常契合。最后,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 脚本时遇到问题,请尝试 awk,如果 awk 不能解决问题,请使用 C,如果 C 仍然失败,请转到 C++。

如何调用awk

如前所述,awk 提供了不同的解决方案来满足许多需求,它们是:

一、awk命令行,可以像普通的UNIX命令一样使用awk,也可以在命令行中使用awk编程语言,虽然awk支持多行输入,但是输入长命令就搞定了对了可能会很头疼,所以这种方法一般只用来解决简单的问题。当然你也可以在shell脚本程序中引用awk命令行甚至是awk程序脚本。

二、使用 -f 选项调用 awk 程序。 awk 允许将 awk 程序写入文本文件,然后在 awk 命令行上使用 -f 选项调用和执行该程序。具体方法我们后面会在awk语法中讲。

三、使用命令解释器调用awk程序:使用UNIX支持的命令解释器功能,我们可以将awk程序写成文本文件,然后添加:

#!/bin/awk -f

并赋予这个文本文件执行权限。完成后,就可以在命令行中调用并执行这个awk程序,方式类似如下。

$awk 脚本文本名称待处理文件

awk 语法:

与其他 UNIX 命令一样,awk 有自己的语法:

awk [ -F re] [参数…] [‘prog’] [-f progfile][in_file…]

参数说明:

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

参数:这个参数有助于为不同的变量赋值。

‘prog’:awk 的程序语句段。此语句段必须包含在单个扩展名中:’ 和 ‘ 以防止它被 shell 解释。该程序段的标准格式为:

‘模式{动作}’

模式参数可以是任何 egrep 正则表达式,可以使用语法 /re/ 加上一些模式匹配技术来形成。与 sed 类似,您也可以使用“,”分隔两种样式以选择范围。具体匹配方式可以参考附件。如果还是不明白,找一本UNIX书籍学习grep和sed(我在学习ed的时候掌握了匹配技术)。 action 参数总是用大括号括起来,它由一个用“;”分隔的 awk 语句系统组成。 awk 解释它们并对匹配由 pattern 给出的模式的记录执行其操作。与 shell 类似,您也可以使用“#”作为注释字符,这使得从“#”到行尾的所有内容都成为注释,并且在解释时将被忽略。您可以省略模式和动作之一,但不能同时省略两者。当省略模式时,没有模式匹配,这意味着对所有行(记录)执行操作。省略 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的第7行到第15行中显示第一个字段、第三个字段和第七个字段,用字符%分隔:

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 语言中的 printf 几乎相同。如果你熟悉 C 语言,可以根据 C 语言模式使用 awk 中的 printf。所以这里只举个例子,不熟悉的可以找一本C语言入门书查一下。

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

$awk ‘{printf”d%s”,NR,$1}’ 我的文件

在命令行中使用 awk

按顺序,我们应该解释一下awk编程的内容,但是在解释之前,我们会用一些例子来复习以前的知识,这些例子都是在命令行中使用的,所以我们可以知道使用awk是多么的方便从命令行。之所以这样,一方面是为后面的内容做铺垫,另一方面是介绍一些解决简单问题的方法。方法。

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

$awk ‘/sun/{print}’ 我的文档

由于显示整条记录(整行)是awk的默认动作,所以动作项可以省略。

$awk ‘/sun/’ 我的文档

示例:以下是更复杂匹配的示例:

$awk ‘/[Ss]un/,/[Mm]oon/ {print}’ 我的文件

它将显示匹配太阳或太阳的第一行与匹配月亮或月亮的第一行之间的线,以标准输出。

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

$awk ‘length($0)>80 {print NR}’ 我的文件

此命令行将显示文本 myfile 中长度超过 80 个字符的所有行号。这里,$0 用于表示整条记录(行),内置变量 NR 不使用标记“$”。

示例:作为一个更实际的示例,我们假设我们要检查 UNIX 中用户的安全性。方法是查看/etc下的passwd文件,检查passwd字段(第二个字段)是否为“*”。 ,如果不是“*”,则表示用户没有设置密码,显示这些用户名(第一个字段)。我们可以通过以下语句做到这一点:

#awk -F: ‘$2==”” {printf(“%s 没有密码!”,$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 还支持逻辑运算符的多重判断:! (不), && (和), || (or) 和括号 (),大大增强了 awk 的功能。本文的附录列出了awk允许的操作、判断和运算符优先级。

awk 的流控制

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

1、开始和结束:

awk中的两个特殊表达式BEGIN和END,都可以在pattern中使用(参考前面的awk语法),提供BEGIN和END的作用是给程序一个初始状态和程序结束后做一些收尾工作。 BEGIN 之后({} 内)列出的任何操作都将在 awk 开始扫描输入之前执行,而 END 之后列出的操作将在扫描整个输入之后执行。因此,BEGIN通常用于显示变量和预设(初始化)变量,END用于输出最终结果。

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

$awk

>’BEGIN { FS=”:”;print “统计销售额”;total=0}

>{打印 $3;total=total+$3;}

>END {printf “总销售额:%.2f”,total}’ sx

(注意:>是shell提供的第二个提示符,如果想在shell程序awk语句和awk语言中换行c语言 脚本解释器,需要在行尾加反斜杠)

这里,BEGIN预设了内部变量FS(字段分隔符)和自定义变量total,并在扫描前显示输出行头。另一方面,END 在扫描完成后打印总数。

2、过程控制语句

awk 提供了完整的流控制语句,其用法与C 语言类似。让我们一一解释:

2.1、if…else 语句:

格式:

如果(表达式)

声明 1

其他

声明 2

格式中的“语句1”可以是多个语句。如果你想让awk更容易自己判断和阅读,你最好用{}括起来多个语句。 awk 分支结构允许嵌套,其格式为:

if(表达式1)

{if(表达式2)

声明 1

其他

声明 2

}

声明 3

else {if(表达式3)

声明 4

其他

声明 5

}

声明 6

当然,你在实际操作过程中可能不会用到这么复杂的分支结构,这里只是给出它的风格。

2.2、while 语句

格式为:

while(表达式)

声明

2.3、do-while 语句

格式为:

{

声明

}while(条件判断语句)

2.4、for 声明

格式为:

for(初始表达式;终止条件;步骤表达式)

{声明}

在awk的while、do-while和for语句中,允许break和continue语句控制流程,也允许exit等语句退出。 break 中断当前执行的循环并跳转到循环外的下一条语句。 continue 从当前位置跳转到循环的开头。 exit 的执行有两种情况:当exit语句不在END时,任何操作中的exit命令都表现为到达文件末尾,所有模式或操作执行都会停止,END模式下的操作是执行。出现在 END 中的退出将导致程序终止。

示例:对于

awk 中的自定义函数

定义和调用用户自己的函数是几乎所有高级语言都有的函数,awk也不例外,但是原来的awk不提供函数函数,只能在nawk或者更新的awk版本中添加函数.

函数的使用由两部分组成:函数定义和函数调用。函数定义又包括要执行的代码(函数本身)和从主程序代码传递给函数的临时调用。

awk函数定义如下:

函数函数名(参数列表){

函数体

}

gawk 允许省略 function as func,但其他版本的 awk 不允许。函数名必须是有效的标识符,参数列表中不能提供任何参数(但调用函数时,函数名后面的一对括号仍然是必不可少的),或者可以提供一个或多个参数。和C语言类似,awk参数也是传值的。

在awk中调用函数比较简单,其方法与C语言类似,但是awk比C语言更灵活,并且不进行参数有效性检查。换句话说,当你调用一个函数时,你可以列出比函数期望的更多或更少的参数(在函数定义中指定),多余的参数会被awk忽略,不足的参数,awk会将它们设置为默认值0或空字符串,无论设置哪个值,都将取决于参数的使用方式。

awk 函数有两种返回方式:隐式返回和显式返回。当 awk 执行到函数末尾时,它会自动返回到调用程序,函数隐式返回。如果您需要在函数完成之前退出函数,您可以显式地使用 return 语句提前退出。这样做的方法是在函数中使用如下形式的语句:return 返回值。

示例:以下示例演示了函数的使用。在本例中,定义了一个名为 print_header 的函数,它调用两个参数 FileName 和 PageNum。 FileName 参数传递给函数当前使用的文件名,PageNum 参数是当前页面的页码。该函数的作用是打印(显示)当前文件的文件名和当前页的页码。该函数执行完毕后,该函数将返回下一页的页码。

不知道

>’BEGIN{pageno=1;file=FILENAME

>pageno=print_header(文件, pageno); #调用函数print_header

>printf(“当前页码为:%d”,pageno);

>}

>#定义函数print_header

>function print_header(FileName,PageNum){

>printf(“%s %d”,FileName,PageNum); >PageNum++;返回PageNUM;

>}

>}’我的文件

执行这个程序会显示如下:

我的文件 1

当前页码为:2

awk 高级输入输出

© 版权声明
THE END
喜欢就支持一下吧
点赞49赞赏 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容