学习Linux命令 - gawk

名称

gawk - 模式扫描和处理语言

概要

gawk [POSIX或GNU风格选项] -f 程序文件 [ - ]文件...
gawk [POSIX或GNU风格选项] [ - ] 程序文本文件...

pgawk [POSIX或GNU风格选项] -f 程序文件 [ - ]文件...
pgawk [POSIX或GNU风格选项] [ - ] 程序文本文件...

描述

GawkGNU项目的AWK编程语言的实现。 它符合POSIX 1003.2命令语言和实用程序标准中语言的定义。 该版本反过来是基于Aho,Kernighan和Weinberger 的AWK编程语言中的描述,以及UNIX awk的System V Release 4版本中的其他功能。 Gawk还提供了更多最新的贝尔实验室awk扩展,以及许多GNU特定的扩展。

Pgawkgawk的简介版本。 除了程序运行速度更慢之外,它与gawk的每种方法都是相同的,并且它在完成时自动在文件awkprof.out中生成执行配置文件。 请参阅下面的--profile选项。

命令行由gawk自身的选项,AWK程序文本(如果不通过-f--file选项提供)以及要在ARGCARGV预定义的AWK变量中可用的值组成。

选项格式

Gawk选项可以是传统的POSIX单字母选项,也可以是GNU风格的长选项。 POSIX选项以单个“ - ”开头,长选项以“ - ”开头。 为GNU特有的功能和POSIX授权的功能提供了很长的选项。

遵循POSIX标准, gawk特定选项通过参数提供给-W选项。 可以提供多个-W选项每个-W选项都有一个相应的长选项,如下所述。 长选项的参数要么通过=符号的选项加入,没有中间空格,要么可以在下一个命令行参数中提供它们。 长选项可能会缩写,只要缩写保持唯一。

选项

Gawk接受以下选项,按字母顺序列出。

-F fs

-字段分隔 fs使用fs作为输入字段分隔符( FS预定义变量的值)。

-v var = val

--assign var = val在程序开始执行之前,将值val分配给变量var 。 这些变量值可用于AWK程序的BEGIN块。

-f 程序文件

--file program-file从文件程序 文件中读取AWK程序源文件 ,而不是从第一个命令行参数中读取。 可以使用多个-f (或--file )选项。

-mf NNN

-mr NNN将各种内存限制设置为NNN值。 f标志设置字段的最大数量, r标志设置最大记录大小。 这两个标志和-m选项来自贝尔实验室研究版UNIX awk 。 它们被gawk忽略,因为gawk没有预先定义的限制。

-W compat

-W传统

--compat

- 传统 兼容模式下运行。 在兼容模式下, gawk的行为与UNIX awk相同; 没有一个GNU特定的扩展被识别。 使用 - 传统优于此选项的其他形式。 有关更多信息,请参见下面的GNU EXTENSIONS

-W copyleft

-W版权

--copyleft

--copyright在标准输出中打印简短版本的GNU版权信息消息并成功退出。

-W转储变量 [ = 文件 ]

--dump-variables [ = file ]打印全局变量,它们的类型和最终值的排序列表。 如果没有提供文件gawk将在当前目录中使用名为awkvars.out的文件。

列出所有全局变量是在程序中查找印刷错误的好方法。 如果你有一个包含很多函数的大型程序,并且你想确保你的函数不会无意中使用你本意的全局变量,那么你也可以使用这个选项。 (这对使用ij等简单变量名称是一个特别容易的错误。)

-W帮助

-W用法

- 帮帮我

--usage在标准输出上打印相对简短的可用选项。 (根据GNU编码标准 ,这些选项会立即成功退出。)

-W棉绒 [ =致命 ]

--lint [ =致命 ]提供有关对其他AWK实现可疑或不可移植的构造的警告。 有了致命的可选参数,皮棉警告成为致命错误。 这可能是激烈的,但它的使用肯定会鼓励开发更清洁的AWK计划。

-W lint-old

--lint-old提供有关不能移植到原始版本的Unix awk的构造的警告。

-W gen-po

--gen-po扫描并解析AWK程序,并在标准输出上生成一个GNU .po格式文件,其中包含程序中所有可本地化字符串的条目。 程序本身没有执行。 有关.po文件的更多信息,请参阅GNU gettext分发。

-W非十进制数据

- 非十进制数据识别输入数据中的八进制和十六进制值。 谨慎使用此选项!

-W posix

--posix这会打开兼容模式,并具有以下附加限制:

*

\ x转义序列无法识别。

*

FS设置为单个空间时,只有空格和制表符用作字段分隔符,而换行符则不是。

*

你不能继续行吗?

*

不能识别关键字功能的同义词func

*

运算符**** =不能用来代替^^ =

*

fflush()函数不可用。

-W配置文件 [ = prof_file ]

--profile [ = prof_file ]将profiling数据发送到prof_file 。 缺省值是awkprof.out 。 在使用gawk运行时,配置文件只是该程序的“漂亮打印”版本。 在使用pgawk运行时,配置文件包含程序中左边界中每个语句的执行计数以及每个用户定义函数的函数调用计数。

-W重新间隔

--re-interval在正则表达式匹配中启用间隔表达式 (请参见下面的正则表达式)。 AWK语言中传统上不提供时间间隔表达式。 POSIX标准添加了它们,以使awkegrep相互一致。 但是,它们的使用很可能会破坏旧的AWK程序,所以如果使用此选项请求或者指定了--posix时, gawk只会提供它们。

-W源程序 文本

--source program-text使用程序文本作为AWK程序源代码。 此选项允许将库函数(通过-f--file选项使用)与源代码在命令行中输入进行轻松混合。 它主要用于shell脚本中使用的大中型AWK程序。

-W版本

--version在标准输出上打印此特定gawk副本的版本信息。 这主要用于了解系统上当前的gawk副本是否与自由软件基金会分发的最新副本一致。 报告错误时这也很有用。 (根据GNU编码标准 ,这些选项会立即成功退出。)

-表示选项结束。 这对允许AWK程序自身以“ - ”开头的更多参数很有用。 这主要是为了与大多数其他POSIX程序使用的参数解析约定保持一致。

在兼容模式下,任何其他选项都会被标记为无效,但会被忽略。 在正常操作中,只要提供了程序文本,就会将未知选项传递给ARGV阵列中的AWK程序进行处理。 这对于通过`#!''可执行文件解释机制运行AWK程序特别有用。

AWK计划执行

一个AWK程序由一系列模式动作语句和可选的函数定义组成。

模式 { 操作语句 }

函数 名称 参数列表 ){ 语句 }

Gawk首先从程序文件 (如果指定)读取程序源,从参数到--source或从命令行中的第一个非选项参数读取程序源。 -f--source选项可以在命令行上多次使用。 Gawk读取程序文本,就好像所有程序文件和命令行源文本已经连接在一起。 这对于构建AWK函数库非常有用,无需将它们包含在每个使用它们的新AWK程序中。 它还提供了将库函数与命令行程序混合的功能。

环境变量AWKPATH指定在查找使用-f选项命名的源文件时要使用的搜索路径。 如果此变量不存在,则默认路径为“。:/ usr / local / share / awk” 。 (实际的目录可能会有所不同,具体取决于gawk的构建和安装方式。)如果给-f选项指定的文件名包含“/”字符,则不执行路径搜索。

Gawk按以下顺序执行AWK程序。 首先,执行通过-v选项指定的所有变量赋值。 接下来, gawk将程序编译成一个内部表单。 然后, gawk执行BEGIN块(如果有的话)中的代码,然后继续读取ARGV数组中指定的每个文件。 如果命令行上没有命名文件,则gawk会读取标准输入。

如果命令行上的文件名具有var = val形式,则将其视为变量赋值。 变量var将被赋值val 。 (在任何BEGIN块运行后会发生这种情况。)命令行变量赋值对动态赋值给变量最有用AWK用来控制输入如何分解为字段和记录。 如果需要通过单个数据文件进行多次传递,则对于控制状态也很有用。

如果ARGV的特定元素的值为空( “” ), gawk会跳过它。

对于输入中的每个记录, gawk会测试它是否与AWK程序中的任何模式相匹配。 对于记录匹配的每个模式,执行关联的操作 。 这些模式按照它们在程序中出现的顺序进行测试。

最后,在所有输入耗尽后, gawk将执行END块中的代码(如果有的话)。

变量,记录和字段

AWK变量是动态的; 它们在第一次使用时就已经存在。 它们的值是浮点数字或字符串,或者两者兼有,取决于它们的使用方式。 AWK也有一维数组; 可以模拟多维的阵列。 几个预先定义的变量被设置为程序运行; 这些将根据需要进行描述并在下面进行总结。

记录

通常,记录由换行符分隔。 您可以通过将值分配给内置变量RS来控制记录的分隔方式。 如果RS是任何单个字符,则该字符将分隔记录。 否则, RS是一个正则表达式。 与此正则表达式匹配的输入中的文本分隔记录。 但是,在兼容模式下,只有字符串值的第一个字符用于分隔记录。 如果RS设置为空字符串,则记录由空行分隔。 当RS设置为空字符串时,除了FS可能具有的任何值之外,换行符总是充当字段分隔符。

字段

当读取每个输入记录时, gawk使用FS变量的值作为字段分隔符将记录拆分为字段 。 如果FS是单个字符,则字段由该字符分隔。 如果FS是空字符串,则每个单独的字符将成为一个单独的字段。 否则, FS预计将是一个完整的正则表达式。 在FS是单个空间的特殊情况下,字段由空格和/或制表符和/或换行符分隔。 (但请参阅下面关于--posix的讨论)。 注意: IGNORECASE的值(见下文)也会影响FS是正则表达式时字段的拆分方式,以及RS是正则表达式时如何分隔记录。

如果FIELDWIDTHS变量设置为以空格分隔的数字列表,则每个字段预计具有固定宽度,并且gawk使用指定的宽度分割记录。 FS的值被忽略。 为FS分配新值将覆盖FIELDWIDTHS的使用,并恢复默认行为。

输入记录中的每个字段可以通过其位置$ 1$ 2等来引用。 $ 0是整个记录。 字段不需要被常量引用:

n = 5
打印$ n

打印输入记录中的第五个字段。

变量NF被设置为输入记录中字段的总数。

引用不存在的字段(即$ NF之后的字段)会生成空字符串。 然而,分配给一个不存在的字段(例如, $(NF + 2)= 5 )会增加NF的值,创建任何以空字符串作为其值的干预字段,并使$ 0的值重新计算,这些字段由OFS的值分隔。 对负数编号字段的引用会导致致命错误。 减少NF会导致超过新值的字段值丢失,并且重新计算$ 0的值,字段之间用OFS值分隔。

为现有字段分配值会导致在引用$ 0时重建整个记录。 同样,将值分配给$ 0将导致记录被重新分割,为这些字段创建新的值。

内置变量

Gawk的内置变量是:

ARGC

命令行参数的数量(不包括gawk选项或程序源)。

ARGIND

正在处理当前文件的ARGV中的索引。

ARGV

命令行参数数组。 数组从索引0到ARGC - 1。动态更改ARGV的内容可以控制用于数据的文件。

BINMODE

在非POSIX系统上,指定对所有文件I / O使用“二进制”模式。 数字值1,2或3指定输入文件,输出文件或所有文件分别应使用二进制I / O。 “r”“w”的字符串值分别指定输入文件或输出文件应使用二进制I / O。 “rw”“wr”的字符串值指定所有文件都应该使用二进制I / O。 任何其他字符串值都被视为“rw” ,但会生成警告消息。

CONVFMT

数字转换格式默认“%.6g”

ENVIRON

包含当前环境值的数组。 该数组由环境变量索引,每个元素都是该变量的值(例如, ENVIRON [“HOME”]可能是/ home / arnold )。 改变这个数组不会影响程序通过重定向或system()函数产生的环境。

ERRNO

如果系统错误发生在getline的重定向, getline读取期间或close()过程中ERRNO将包含描述错误的字符串。 该值需要在非英文语言环境中进行翻译。

FIELDWIDTHS

以空格分隔的字段宽度列表。 设置时, gawk将输入分析为固定宽度的字段,而不是将FS变量的值用作字段分隔符。

文件名

当前输入文件的名称。 如果在命令行上没有指定文件, FILENAME的值是`` - ''。 但是, FILENAMEBEGIN块内部是未定义的(除非由getline设置)。

FNR

当前输入文件中的输入记录编号。

FS

输入字段分隔符,默认为空格。 请参阅上面的字段

IGNORECASE

控制所有正则表达式和字符串操作的区分大小写。 如果IGNORECASE具有非零值,则规则中的字符串比较和模式匹配, FS中的字段拆分, RS记录分隔,与!〜匹配的正则表达式以及gensub()gsub()index()match()split()sub()内置函数在执行正则表达式操作时都会忽略大小写。 注:数组下标不受影响, asort()函数也不受影响。

因此,如果IGNORECASE不等于零,则/ aB /匹配所有字符串“ab”“aB”“Ab”“AB” 。 与所有AWK变量一样, IGNORECASE的初始值为零,因此所有正则表达式和字符串操作通常都区分大小写。 在Unix下,忽略大小写时使用完整的ISO 8859-1 Latin-1字符集。

皮棉

在AWK程序中提供对--lint选项的动态控制。 如果属实, gawk将打印lint警告。 如果错误,它不会。 当分配字符串值“致命”时 ,lint警告成为致命错误,就像--lint =致命 。 任何其他真正的价值只是打印警告。

NF

当前输入记录中的字段数。

NR

迄今为止看到的输入记录总数。

OFMT

数字的输出格式默认“%.6g”

OFS

输出字段分隔符默认为空格。

ORS

输出记录分隔符默认为换行符。

PROCINFO

此数组的元素提供有关正在运行的AWK程序的信息。 在某些系统中,阵列中可能存在元素, “group1”“group n 对于某些n ,这是进程所具有的补充组的数量。 使用in运算符来测试这些元素。 以下元素保证可用:

PROCINFO [ “EGID”]

getegid (2)系统调用的值。

PROCINFO [ “EUID”]

geteuid (2)系统调用的值。

PROCINFO [ “FS”]

如果使用FS进行场分割,则为“FS”;如果使用FIELDWIDTHS进行场分割,则使用“FIELDWIDTHS”

PROCINFO [ “GID”]

getgid (2)系统调用的值。

PROCINFO [ “pgrpid”]

当前进程的进程组ID。

PROCINFO [ “PID”]

当前进程的进程ID。

PROCINFO [ “PPID”]

当前进程的父进程ID。

PROCINFO [ “UID”]

getuid (2)系统调用的值。

RS

输入记录分隔符默认为换行符。

RT

记录终结者。 GawkRT设置为与RS指定的字符或正则表达式匹配的输入文本。

RSTART

match()匹配的第一个字符的索引; 如果不匹配,则为0。 (这意味着人物指数从一开始。)

RLENGTH

match()匹配的字符串的长度; -1如果不匹配。

SUBSEP

用于分隔数组元素中多个下标的字符,默认为“\ 034”

TEXTDOMAIN

AWK程序的文本域; 用于查找程序字符串的本地化翻译。

数组

数组的下标用方括号( [] )之间的表达式表示。 如果表达式是表达式列表( exprexpr ...),则数组下标是由每个表达式的(字符串)值的串联组成的字符串,由SUBSEP变量的值分隔。 该工具用于模拟多维数组。 例如:

我=“A”; j =“B”; k =“C”
x [i,j,k] =“你好,世界\ n”

将字符串“hello,world \ n”分配给由字符串“A \ 034B \ 034C”索引的数组x的元素。 AWK中的所有数组都是关联的,即通过字符串值进行索引。

特殊运算符可以用于ifwhile语句,以查看数组是否具有由特定值组成的索引。

如果(数组中的val)打印数组[val]

如果数组有多个下标,则使用数组中的(i,j)

in构造也可以用于for循环来遍历数组的所有元素。

可以使用delete语句从数组中删除一个元素。 删除语句也可以用来删除数组的全部内容,只需指定没有下标的数组名即可。

可变键入和转换

变量和字段可能是(浮点)数字或字符串,或两者兼而有之。 如何解释变量的值取决于其上下文。 如果用在数字表达式中,它将被视为一个数字,如果作为字符串使用,它将被视为字符串。

要强制一个变量被视为一个数字,请给它加0; 强制它被视为一个字符串,并将其与空字符串连接起来。

当必须将字符串转换为数字时,转换将使用strtod (3)完成。 通过使用CONVFMT的值作为sprintf (3)的格式字符串将数字转换为字符串,并将变量的数值作为参数。 但是,尽管AWK中的所有数字都是浮点数,但整数值总是被转换为整数。 因此,给出

CONVFMT =“%2.2f”a = 12 b = a“”

变量b的字符串值为“12”而不是“12.00”

Gawk执行如下比较:如果两个变量是数字,则它们在数字上进行比较。 如果一个值是数字,而另一个值是一个“数字字符串”的字符串值,那么比较也是以数字方式完成的。 否则,数字值将转换为字符串,并执行字符串比较。 当然,将两个字符串作为字符串进行比较。 请注意,POSIX标准将“数字字符串”的概念应用于任何地方,甚至应用于字符串常量。 然而,这显然是不正确的,而gawk并没有这样做。 (幸运的是,这在标准的下一个版本中得到了修复。)

请注意,字符串常量(如“57”不是数字字符串,它们是字符串常量。 “数字字符串”的概念仅适用于字段, getline输入, FILENAMEARGV元素, ENVIRON元素以及由split()创建的数组元素,它们都是数字字符串。 基本思想是用户输入 ,只有用户输入,看起来数字,应该这样处理。

未初始化的变量具有数字值0和字符串值“”(空或空字符串)。

八进制和十六进制常量

gawk 3.1版开始您可以在AWK程序源代码中使用C风格的八进制和十六进制常量。 例如,八进制值011等于十进制数9 ,而十六进制值0x11等于十进制数17。

字符串常量

AWK中的字符串常量是包含在双引号( )之间的字符序列。在字符串中,某些转义序列被识别,如C中所示。它们是:

\\

字面反斜杠。

\一个

“警报”字符; 通常是ASCII BEL字符。

\ b

退格。

\F

形式喂。

\ n

新队。

\ r

回车。

\ t

水平标签。

符\ v

垂直标签。

\ x 十六进制数字

\ x后面的十六进制数字字符串表示的字符。 和ANSIC一样,所有后面的十六进制数字都被认为是转义序列的一部分。 (这个特性应该告诉我们关于委员会语言设计的一些东西。)例如, “\ x1B”是ASCIIESC(逃逸)角色。

\ ddd

由1位,2位或3位八进制数字序列表示的字符。 例如, “\ 033”是ASCII ESC(转义)字符。

\ c

字面字符c

转义序列也可以在常量表达式中使用(例如, / [\ t \ f \ n \ r \ v] /匹配空格字符)。

在兼容模式下,在正则表达式常量中使用八进制和十六进制转义序列表示的字符时会逐字处理。 因此, / a \ 52b /相当于/ a \ * b /

模式和行动

AWK是一种面向行的语言。 模式首先,然后是行动。 Action语句包含在{}中 。 模式可能会丢失,或者动作可能会丢失,但当然不是两种。 如果缺少模式,则对每个输入记录都执行该操作。 缺少的操作相当于

{print}

打印整个记录。

注释以“#”字符开始,并一直持续到行尾。 空白行可用于分隔语句。 通常情况下,语句以换行符结束,但是,对于以``,'', { ,?结尾的行不是这种情况&&|| 。 以doelse结尾的也会自动在下面一行继续。 在其他情况下,可以通过以'结束'来继续一行,在这种情况下,换行符将被忽略。

多个语句可以通过用``;'分隔它们在一行上。 这适用于模式动作对(通常情况下)的动作部分内的语句以及模式动作语句本身。

模式

AWK模式可能是以下之一:

BEGIN END / 正则表达式 / 关系表达式 模式 && 模式 模式 || 模式 模式 图案 图案 图案 模式 pattern1 pattern2

BEGINEND是两种特殊类型的模式,不针对输入进行测试。 所有BEGIN模式的动作部分被合并,就好像所有的语句都被写入了一个BEGIN块一样。 它们在读取任何输入之前执行。 类似地,所有END块都被合并,并在所有输入耗尽时(或执行退出语句时)执行。 BEGINEND模式不能与模式表达式中的其他模式组合。 BEGINEND模式不能缺少动作部分。

对于/ 正则表达式 /模式,将为每个与正则表达式匹配的输入记录执行关联语句。 正则表达式与egrep (1)中的正则表达式相同,总结如下。

关系表达式可以使用以下在操作部分定义的任何操作符。 这些通常测试某些字段是否匹配某些正则表达式。

&&|| ,和 运算符分别与C中的逻辑AND,逻辑OR和逻辑NOT一样。它们也像C中一样进行短路评估,并用于组合更多原始模式表达式。 和大多数语言一样,可以使用括号来改变评估顺序。

?:操作符与C中的相同操作符相同。如果第一个模式为true,则用于测试的模式是第二个模式,否则是第三个模式。 只评估第二种和第三种模式中的一种。

表达式的pattern1 pattern2形式称为范围模式 。 它匹配以匹配pattern1的记录开始的所有输入记录,并且一直持续到匹配pattern2 (包含)的记录。 它不与任何其他类型的模式表达式结合使用。

常用表达

正则表达式是egrep中的扩展类型。 它们由以下字符组成:

C

匹配非元字符c

\C

匹配文字字符c

匹配任何字符, 包括换行符。

^

匹配字符串的开头。

$

匹配字符串的结尾。

[ abc ... ]

字符列表,匹配任何字符abc ...。

[^ abc ... ]

否定字符列表,匹配除abc之外的任何字符...。

r1 | R2

交替:匹配r1r2

R1R2

连接:匹配r1 ,然后匹配r2

r +

匹配一个或多个r

r *

匹配零个或多个r

r

匹配零个或一个r

r

分组:匹配r

r { n }

r { n ,}

r { n m }花括号中的一个或两个数字表示间隔表达式 。 如果大括号中有一个数字,则前面的正则表达式r重复n次。 如果有两个数字用逗号分隔,则r重复nm次。 如果有一个数字后跟一个逗号,则r至少重复n次。

只有在命令行中指定了--posix--re-interval,才能使用间隔表达式。

\ÿ

匹配单词开头或结尾的空字符串。

\乙

匹配单词中的空字符串。

\ <

匹配单词开始处的空字符串。

\>

匹配单词末尾的空字符串。

\ W

匹配任何单词组成字符(字母,数字或下划线)。

\ W

匹配任何不是以字为单位的字符。

\`

匹配缓冲区(字符串)开始处的空字符串。

''

匹配缓冲区末尾的空字符串。

在字符串常量中有效的转义序列(见下文)在正则表达式中也是有效的。

字符类是POSIX标准中引入的一项新功能。 字符类是用于描述具有特定属性的字符列表的特殊符号,但是实际字符本身可能因国家/地区和/或字符集到字符集而异。 例如,在美国和法国,什么是字母字符的概念是不同的。

字符类仅在字符列表的括号的正则表达式中有效。 字符类由[: ,表示类的关键字和:]组成 。 由POSIX标准定义的字符类是:

[:alnum:]

字母数字字符。

[:α:]

字母字符。

[:空白:]

空格或制表符。

[:CNTRL:]

控制字符。

[:数字:]

数字字符。

[:图形:]

既可打印又可见的字符。 (空格是可打印的,但不可见,而a是两者。)

[:降低:]

小写字母字符。

[:打印:]

可打印字符(不是控制字符的字符)。

[:PUNCT:]

标点字符(不是字母,数字,控制字符或空格字符的字符)。

[:空间:]

空格字符(例如空格,制表符和换页符等等)。

[:上:]

大写字母字符。

[:xdigit:]

字符是十六进制数字。

例如,在POSIX标准之前,为了匹配字母数字字符,您必须编写/ [A-Za-z0-9] / 。 如果您的字符集中包含其他字母字符,则这些字符与它们不匹配,并且如果您的字符集与ASCII的排序方式不同,这可能甚至不匹配ASCII字母数字字符。 使用POSIX字符类,您可以编写/ [[:alnum:]] / ,这与字符集中的字母和数字字符相匹配。

在字符列表中可以出现两个额外的特殊序列。 这些适用于非ASCII字符集,它可以具有多个字符表示的单个符号(称为整理元素 ),以及用于整理或排序目的相当的几个字符。 (例如,用法语,一个简单的“e”和一个带重音符号的e是相同的。)

整理符号

整理符号是一个多字符整理元素,封闭在[。] 。 例如,如果ch是一个整理元素,那么[[.ch。]]是一个匹配此整理元素的正则表达式,而[ch]是一个匹配ch的正则表达式。

等同类

等价类是等价的字符列表的特定于语言环境的名称。 名称包含在[==]中 。 例如,名字e可以用来表示所有的“e”,“e”,“'和”e“。'在这种情况下, [[= e =]]是一个正则表达式匹配ee'e`中的任何一个。

这些功能在非英语语言环境中非常有用。 gawk用于正则表达式匹配的库函数目前仅识别POSIX字符类; 他们不识别整理符号或等价类。

\ y\ B\ <\>\ w\ W\\'操作符是特定于gawk的 ; 它们是基于GNU正则表达式库中的设施的扩展。

各种命令行选项控制gawk如何解释正则表达式中的字符。

没有选择

在默认情况下, gawk提供了上述POSIX正则表达式和GNU正则表达式运算符的所有功能。 但是,不支持区间表达式。

--posix

只支持POSIX正则表达式,GNU运算符并不特殊。 (例如\ w匹配文字w )。 间隔表达式是允许的。

--traditional

传统的Unix awk正则表达式是匹配的。 GNU运算符不是特殊的,区间表达式不可用,也不是POSIX字符类( [[:alnum:]]等等)。 由八进制和十六进制转义序列描述的字符被字面处理,即使它们表示正则表达式元字符。

--re间隔

即使已提供--traditional ,也允许在正则表达式中使用区间表达式。

操作

Action语句包含在大括号{}中 。 Action语句由大多数语言中常见的赋值语句,条件语句和循环语句组成。 可用的操作符,控制语句和输入/输出语句在C中的那些模式之后形成图案。

运营商

AWK中的运算符按优先级递减顺序排列

...

分组

$

字段参考。

++ -

增量和减量,前缀和后缀。

^

指数运算( **也可以使用, ** =用于赋值运算符)。

+ - !

一元加,一元减,逻辑否定。

* /%

乘法,除法和模数。

+ -

加减。

空间

字符串连接。

<>

<=> =

!= ==常规的关系运算符。

〜!〜

正则表达式匹配,否定匹配。 注意:请勿在!〜的左侧使用常量正则表达式( / foo / )。 只在右侧使用一个。 表达式/ foo / 〜exp的含义与(($ 0〜/ foo /) 〜exp )相同 。 这通常不是预期的。

数组成员。

&&

逻辑AND。

||

逻辑或。

C条件表达式。 这有形式expr1 expr2 expr3 。 如果expr1为true,则表达式的值为expr2 ,否则为expr3 。 只评估expr2expr3中的一个。

= + = - =

* = / =%= ^ =分配。 支持绝对赋值 var = value 和运算符赋值(其他形式)。

控制陈述

控制声明如下:

if( condition 语句 [ else 语句 ] while( condition 语句 do 语句 while( condition for( expr1 ; expr2 ; expr3 语句 for( var in array 语句 break 继续 删除 array [ index ] delete array exit [ expression ] { 语句 }

I / O语句

输入/输出语句如下所示:

关闭( 文件 [ 如何 ]

关闭文件,管道或协同处理。 只有在将双向管道的一端关闭到协同进程时才可以使用该选项。 它必须是一个字符串值,可以是“to”“from”

函数getline

从下一个输入记录中设置$ 0 ; 设置NFNRFNR

getline < 文件

文件的下一个记录中设置$ 0 ; 设置NF

getline var

从下一个输入记录中设置var ; 设置NRFNR

getline var < 文件

从下一个文件记录中设置var

命令 | getline [ var ]

运行命令将输出连接到$ 0var ,如上所述。

命令 |&getline [ var ]

运行命令作为一个协处理过程将输出传递到$ 0var ,如上所述。 协同过程是一个gawk扩展。

下一个

停止处理当前输入记录。 下一个输入记录被读取,处理将在AWK程序中的第一个模式开始。 如果达到输入数据的结尾,则执行END块(如果有)。

下一文件

停止处理当前的输入文件。 下一个输入记录读取来自下一个输入文件。 FILENAMEARGIND被更新, FNR被重置为1,并且AWK程序中的第一个模式重新开始处理。 如果达到输入数据的结尾,则执行END块(如果有)。

打印

打印当前记录。 输出记录以ORS变量的值结束。

打印 expr列表

打印表达式。 每个表达式都由OFS变量的值分隔。 输出记录以ORS变量的值结束。

打印 expr-list > 文件

文件上打印表达式。 每个表达式都由OFS变量的值分隔。 输出记录以ORS变量的值结束。

printf fmt,expr-list

格式和打印。

printf fmt,expr-list > 文件

格式化并打印文件

系统( cmd-line

执行命令cmd-line ,并返回退出状态。 (这可能不适用于非POSIX系统。)

fflush( [ 文件 ]

刷新与打开的输出文件或管道文件相关联的任何缓冲区。 如果文件丢失,则标准输出将被刷新。 如果file是空字符串,则所有打开的输出文件和管道都会刷新其缓冲区。

printprintf允许额外的输出重定向。

打印... >> 文件

将输出附加到文件

打印... | 命令

写在管道上。

打印... |& 命令

将数据发送到协同进程。

getline命令在文件结尾处返回0,在错误时返回-1。 出错时, ERRNO包含描述问题的字符串。

注意:如果使用管道或协同处理来获取循环,或者通过循环中的printprintf ,则必须使用close()来创建命令的新实例。 AWK在返回EOF时不会自动关闭管道或协同进程。

printf声明

printf语句和sprintf()函数的AWK版本(见下文)接受以下转换规范格式:

%C

一个ASCII字符。 如果用于%c的参数是数字,则将其视为字符并进行打印。 否则,该参数被假定为一个字符串,并且该字符串的唯一第一个字符被打印出来。

%d%i

一个十进制数(整数部分)。

%e,%E

一个形式为[ - ] d.dddddde [+ - ] dd的浮点数%E格式使用E而不是e

%F

一个形式为[ - ] ddd.dddddd的浮点数

%g,%G

使用%e%f转换,以较短者为准,禁止显着的零。 %G格式使用%E而不是%e

Ø%

一个无符号的八进制数(也是一个整数)。

%u一个无符号的十进制数(又是一个整数)。

%S

一个字符串。

%x,%X

无符号的十六进制数字(整数)。 %X格式使用ABCDEF而不是abcdef

%%

单个字符; 没有参数被转换。

可选的,额外的参数可能位于和控制字母之间:

计数 $

在格式化的这一点上使用count'th参数。 这称为位置说明符 ,主要用于格式字符串的翻译版本,而不是AWK程序的原始文本。 这是一个gawk扩展。

-

该表达应在其领域内左对齐。

空间

对于数字转换,前缀为正值,空格为负值,负号为负值。

+

在宽度修饰符(见下文)之前使用的加号表示始终为数字转换提供一个符号,即使要格式化的数据为正数。 +覆盖空格修饰符。

对某些控制字母使用“替代形式”。 对于%o ,提供一个前导零。 对于%x%X ,为非零结果提供前导的0x0X 。 对于%e%E%f ,结果始终包含一个小数点。 对于%g%G ,尾部零不会从结果中删除。

0

前导0 (零)用作标志,表示输出应该用零填充而不是空格。 这甚至适用于非数字输出格式。 此标志仅在字段宽度比要打印的值宽时才起作用。

宽度

该字段应填充到此宽度。 该字段通常用空格填充。 如果0标志已被使用,则用0填充。

PREC

指定打印时使用的精确度的数字。 对于%e%E%f格式,这指定了您想要打印到小数点右侧的位数。 对于%g%G格式,它指定了有效位数的最大值。 对于%d%o%i%u%x%X格式,它指定要打印的最小位数。 对于%s ,它指定应该打印的字符串的最大字符数。

ANSI C printf()例程的动态宽度预先功能均受支持。 A *代替宽度或预定义规格会使它们的值从参数列表中获取到printfsprintf() 。 要使用具有动态宽度或精度的位置说明符,请在格式字符串中的*之后提供计数 $ 。 例如, “%3 $ * 2 $。* 1 $ s”

特殊文件名称

当从printprintf执行I / O重定向到文件或通过文件中的getline进行时, gawk会在内部识别某些特殊文件名。 这些文件名允许访问从gawk的父进程(通常是shell)继承的打开的文件描述符。 这些文件名也可用于命令行命名数据文件。 文件名是:

的/ dev /标准输入

标准输入。

的/ dev /标准输出

标准输出。

的/ dev /标准错误

标准错误输出。

/ dev / fd / n

与打开的文件描述符n关联的文件。

这些对于错误消息特别有用。 例如:

打印“你吹了它!” >“/ dev / stderr”

否则你将不得不使用

打印“你吹了它!” | “猫1&2”

以下特殊文件名可用于|& co-process操作员以创建TCP / IP网络连接。

/ inet / tcp / lport / rhost / rport

本地端口lport上的TCP / IP连接文件到远程端口rport上的远程主机rhost 。 使用0端口让系统选择一个端口。

/ inet / udp / lport / rhost / rport

类似的,但使用UDP / IP而不是TCP / IP。

/ inet / raw / lport / rhost / rport

保留以供将来使用。

其他特殊文件名可以访问有关正在运行的gawk进程的信息。 这些文件名现在已经过时。 使用PROCINFO数组获取它们提供的信息。 文件名是:

的/ dev / PID

读取该文件将返回当前进程的进程ID(十进制),并以换行符结尾。

的/ dev / PPID

读取该文件将返回当前进程的父进程ID(十进制),并以换行符结尾。

的/ dev / pgrpid

读取此文件将返回当前进程的进程组标识(十进制),并以换行符结尾。

的/ dev /用户

读取此文件将返回以换行符结尾的单个记录。 这些字段用空格分隔。 $ 1getuid (2)系统调用的值, $ 2geteuid (2)系统调用的值, $ 3getgid (2)系统调用的值, $ 4getegid (2)的值。系统调用。 如果有其他字段,则它们是由getgroups (2)返回的组ID。 所有系统可能不支持多个组。

数字函数

AWK具有以下内置的算术功能:

atan2( y x

以弧度返回y / x的反正切值。

cos( expr

返回以弧度表示的expr的余弦值。

exp( expr

指数函数。

int( expr

截断为整数。

日志( expr

自然对数函数。

RAND()

返回0到1之间的随机数。

罪( expr

返回expr的正弦值,以弧度表示。

sqrt( expr

平方根函数。

srand( [ expr ]

expr用作随机数生成器的新种子。 如果没有提供expr ,则使用一天中的时间。 返回值是随机数生成器的先前种子。

字符串函数

Gawk具有以下内置的字符串函数:

asort( s [ d ]

返回源数组中元素数量。 s的内容使用gawk用于比较值的正常规则进行排序, s的排序值的索引用从1开始的顺序整数替换。如果指定了可选目标数组d ,则首先将s复制到d ,然后对d进行排序,从而保持源数组索引不变。

gensub( r s h [ t ]

在目标字符串t中搜索正则表达式r的匹配项。 如果h是以gG开头的字符串,则用s替换r的所有匹配项。 否则, h是一个数字,表示要替换r的哪个匹配项。 如果未提供t ,则使用$ 0 。 在替换文本s中 ,序列\ n (其中n是从1到9的数字)可用于仅指示匹配第n个加括号的子表达式的文本。 序列\ 0表示整个匹配的文本,就像字符&一样 。 与sub()gsub()不同 ,修改后的字符串作为函数的结果返回,原始目标字符串不会更改。

gsub( r s [ t ]

对于与字符串t中的正则表达式r匹配的每个子字符串,替换字符串s ,并返回替换的数量。 如果未提供t ,请使用$ 0 。 替换文本中的替换为实际匹配的文本。 使用\&获得一个文字 。 (必须输入“\\&” ;参见GAWK:有效的AWK编程 ,以更全面地讨论sub()gsub()gensub()的替换文本中的和反斜杠的规则。

指数( s t

返回字符串s中字符串t的索引,如果t不存在,则返回0。 (这意味着人物指数从一开始。)

长度( [ s ]

返回字符串 s的长度,如果未提供s ,则返回 $ 0的长度。

match( s r [ a ]

返回正则表达式r出现的s中的位置,如果r不存在,则返回0,并设置RSTARTRLENGTH的值。 请注意,参数顺序与运算符相同: str〜re 。 如果提供数组a ,则清除a,然后元素1到n填充s中与r中的相应括号子表达式匹配的部分。 a的第0个元素包含由整个正则表达式r匹配的s部分。

split( s a [ r ]

将字符串s分解到正则表达式r上的数组a中 ,并返回字段数。 如果r省略,则使用FS 。 数组a先被清除。 如上所述,分裂行为与场分裂相同。

sprintf( fmt expr-list

根据fmt打印expr-list ,并返回结果字符串。

strtonum( str

检查str ,并返回其数值。 如果str 以前导 0开始, strtonum()假定str是八进制数。 如果str从前导的0x0X开始strtonum()就认为str是一个十六进制数字。

sub( r s [ t ]

就像gsub()一样 ,但只有第一个匹配的子字符串被替换。

substr( s i [ n ]

返回从i开始的最多n个字符的子字符串。 如果省略n ,则使用其余的s

tolower( str

返回字符串str的一个副本,将str中的所有大写字符转换为其对应的小写字母。 非字母字符保持不变。

toupper( str

返回字符串str的一个副本,将str中的所有小写​​字符转换为其对应的大写字母。 非字母字符保持不变。

时间函数

由于AWK程序的主要用途之一是处理包含时间戳记信息的日志文件,因此gawk提供以下函数来获取时间戳记和格式化它们。

mktime( datespec

将日期规范转换为与systime()返回的形式相同的时间戳。 datespec是一个形式为YYYY MM DD HH MM SS [DST]的字符串。 字符串的内容是六个或七个数字,分别表示全年,包括世纪,从1到12的月份,从1到31的月份的日期,从0到23的一天中的小时,从0到分钟的分钟59,第二个从0到60,以及可选的夏令时标志。 这些数字的值不需要在指定的范围内; 例如,1小时-1表示午夜前1小时。 假设原点零公历零日历,第0年在第1年和第-1年之前的第0年。时间假定在当地时区。 如果夏令时标志为正,则时间假定为夏令时; 如果为零,则假定时间为标准时间; 如果为负值(默认值),则mktime()将尝试确定夏令时是否对指定时间有效。 如果datespec没有包含足够的元素或结果时间超出范围,则mktime()返回-1。

strftime( [ format [ timestamp ]]

根据格式规格格式化时间戳 时间戳应该与systime()返回的格式相同。 如果缺少时间戳 ,则使用当前的一天中的时间。 如果缺少格式,则使用等同于日期 (1)输出的默认格式。 请参阅ANSI C中strftime()函数的规范,了解可确保可用的格式转换。 strftime (3)的公共域版本和它的手册页带有gawk ; 如果该版本用于构建gawk ,那么该手册页中描述的所有转换都可用于gawk。

SYSTIME()

从Epoch(POSIX系统的1970-01-01 00:00:00 UTC)开始的秒数返回当前时间。

位操作函数

gawk版本3.1开始,下列位操作函数可用。 它们通过将双精度浮点值转换为无符号长整型,执行操作,然后将结果转换回浮点型来工作。 功能是:

和( v1 v2

返回由v1v2提供的值的按位与。

compl( val

返回val的按位补码。

lshift( val count

返回val的值,左移计数位。

或( v1 v2

返回由v1v2提供的值的按位或。

rshift( val count

返回val的值,右移计数位。

xor( v1 v2

返回由v1v2提供的值的按位XOR。

国际化职能

gawk版本3.1开始,可以在AWK程序中使用以下函数来在运行时翻译字符串。 有关完整的详细信息,请参阅GAWK:有效的AWK编程

bindtextdomain( directory [ domain ]

指定gawk查找.mo文件的目录,以防它们不能或不能放置在“标准”位置(例如,在测试期间)。 它返回被绑定的目录。''

默认TEXTDOMAIN的值。 如果directory是空字符串( “” ),则bindtextdomain()返回给定的当前绑定。

dcgettext( string [ domain [ category ]]

返回区域设置类别类别的文本域域中 字符串的翻译。 的默认值是TEXTDOMAIN的当前值。 类别的默认值是“LC_MESSAGES”

如果您为类别提供值,则它必须是一个等于GAWK:有效AWK编程中所述的已知语言环境类别之一的字符串。 您还必须提供文本域。 如果您想使用当前域,请使用TEXTDOMAIN

dcngettext( string1string2number [ domain [ category ]]

返回用于区域设置类别类别的文本域域中字符串1字符串2的翻译编号的复数形式。 的默认值是TEXTDOMAIN的当前值。 类别的默认值是“LC_MESSAGES”

如果您为类别提供值,则它必须是一个等于GAWK:有效AWK编程中所述的已知语言环境类别之一的字符串。 您还必须提供文本域。 如果您想使用当前域,请使用TEXTDOMAIN

用户定义的函数

AWK中的函数定义如下:

函数 名称 参数列表 ){ 语句 }

当函数在表达式中以模式或动作调用时执行。 函数调用中提供的实际参数用于实例化函数中声明的形式参数。 数组通过引用传递,其他变量按值传递。

由于函数本来不是AWK语言的一部分,因此对局部变量的规定相当笨拙:它们在参数列表中声明为额外的参数。 约定是通过参数列表中的额外空格将局部变量与真实参数分开。 例如:

函数f(p,q,a,b)#a和b是本地{...} / abc / {...; f(1,2); ...}

函数调用中的左括号需要立即跟随函数名称,而不需要任何中间空白。 这是为了避免使用连接运算符的语法歧义。 此限制不适用于上面列出的内置功能。

函数可能会互相调用,并且可能是递归的。 用作局部变量的函数参数在函数调用时被初始化为空字符串和数字零。

使用return expr从函数返回一个值。 如果没有提供任何值,或者函数通过“下降”结束返回值,则返回值不确定。

如果提供了--lintgawk会在解析时调用未定义的函数,而不是在运行时发出警告。 在运行时调用未定义的函数是一个致命错误。

func这个词可以用来代替功能

动态加载新功能

gawk版本3.1开始,您可以动态地向运行的gawk解释器添加新的内置函数。 完整的细节超出了本手册页面的范围; 有关详细信息,请参阅GAWK:有效的AWK编程

扩展名( 对象 功能

动态链接由object指定的共享对象文件并调用该对象中的函数以执行初始化。 这些都应该作为字符串提供。 返回函数返回的值。

GAWK:有效的AWK编程提供并记录了此功能,但有关此功能的一切可能会在下一版本中发生变化。 我们强烈建议您不要将此功能用于您不愿意重做的任何事情。

SIGNALS

pgawk接受两个信号。 SIGUSR1会导致它将一个配置文件和函数调用堆栈转储到配置文件,该配置文件可能是awkprof.out ,或者是使用--profile选项命名的任何文件。 然后它继续运行。 SIGHUP导致它转储配置文件和函数调用堆栈,然后退出。

例子

打印并排序所有用户的登录名: BEGIN {FS =“:”} {print $ 1 | “sort”}}对文件中的行进行计数: {nlines ++} END {print nlines}在文件前面加上每行的编号: {print FNR,$ 0}连接和行号(主题变体): {print NR, $ 0}

内在

字符串常量是用双引号括起来的字符序列。 在非英语环境中,可以在AWK程序中将字符串标记为需要翻译为本地自然语言。 这些字符串在AWK程序中用一个前导下划线(``_'')标记。 例如,

gawk'BEGIN {print“hello,world”}'

总是打印你好,世界 。 但,

gawk'BEGIN {print _“hello,world”}'

可能会在法国打印bonjour,monde

生成和运行可本地化的AWK程序涉及多个步骤。

1。

添加BEGIN操作,为TEXTDOMAIN变量赋值,将文本域设置为与程序关联的名称。


BEGIN {TEXTDOMAIN =“myprog”}

这允许gawk找到与你的程序相关的.mo文件。 如果没有这一步, gawk将使用消息文本域,该域可能不包含程序翻译。

2。

标记应该用前导下划线翻译的所有字符串。

3。

如有必要,酌情在程序中使用dcgettext()和/或bindtextdomain()函数。

4。

运行gawk --gen-po -f myprog.awk> myprog.po为你的程序生成一个.po文件。

5。

提供适当的翻译,并建立和安装相应的.mo文件。

GAWK中详细介绍了国际化功能:有效的AWK编程

Posix兼容性

gawk的主要目标是与POSIX标准以及最新版本的UNIX awk兼容。 为此, gawk集成了以下用户可见的特性,这些特性在AWK书中没有描述,但是是贝尔实验室版本的awk的一部分 ,并且符合POSIX标准。

该书指出,当awk以其他方式将参数作为文件打开时(这是BEGIN块执行之后),会发生命令行变量赋值。 但是,在早期的实现中,当这种分配出现在任何文件名之前时,分配将 BEGIN块运行之前发生。 应用程序依赖于这个“特性”。当awk被修改为与其文档相匹配时,添加-v选项以在程序执行前分配变量,以适应​​依赖于旧行为的应用程序。 (这个特性得到了贝尔实验室和GNU开发者的同意。)

实现特定功能的-W选项来自POSIX标准。

处理参数时, gawk使用特殊选项`` - ''来表示参数的结束。 在兼容模式下,它会发出警告,否则会忽略未定义的选项。 在正常操作中,这些参数被传递给AWK程序进行处理。

AWK书没有定义srand()的返回值。 POSIX标准会返回它使用的种子,以便跟踪随机数字序列。 因此, gawk中的 srand()也返回当前的种子。

其他新功能有:使用多个-f选项(来自MKS awk ); ENVIRON阵列; \ a\ v转义序列(最初在gawk中完成并反馈到贝尔实验室版本中); tolower()toupper()内置函数(来自贝尔实验室版本); 和printf中的ANSI C转换规范(在贝尔实验室版本中首次完成)。

历史特征

gawk支持的历史AWK实现有两个特性。 首先,不仅可以在没有参数的情况下调用length()内置函数,但即使没有括号! 从而,

a =长度#Holy Algol 60,蝙蝠侠!

和其中任何一个一样

a =长度()
a =长度($ 0)

这个特性在POSIX标准中被标记为“deprecated”,如果在命令行中指定了--lintgawk会发出一个关于其使用的警告。

另一个特性是在一段时间内 ,使用continuebreak语句, fordo循环。 传统的AWK实现将这种用法视为等同于下一个语句。 如果已经指定--traditional,Gawk支持这种用法。

GNU扩展

Gawk有许多对POSIX awk的扩展。 它们在本节中描述。 通过使用--traditional选项调用gawk ,可以禁用此处描述的所有扩展。

gawk的以下功能在POSIX awk中不可用。

*

对通过-f选项命名的文件不执行路径搜索。 因此AWKPATH环境变量不是特殊的。

*

\ x转义序列。 (使用--posix禁用。)

*

fflush()函数。 (使用--posix禁用。)

*

继续行后的能力 。 (使用--posix禁用。)

*

AWK程序中的八进制和十六进制常量。

*

ARGINDBINMODEERRNOLINTRTTEXTDOMAIN变量并不特殊。

*

IGNORECASE变量及其副作用不可用。

*

FIELDWIDTHS变量和固定宽度的字段拆分。

*

PROCINFO数组不可用。

*

RS用作正则表达式。

*

无法识别可用于I / O重定向的特殊文件名。

*

用于创建协同过程的|&运算符。

*

能够使用空字符串作为FS的值分割出单个字符,并作为split()的第三个参数。

*

close()函数的可选第二个参数。

*

match()函数的可选第三个参数。

*

使用位置说明符printfsprintf()的能力

*

使用delete 数组 删除 数组的全部内容。

*

使用nextfile放弃当前输入文件的处理。

*

()asort()bindtextdomain()compl()dcgettext()gensub()lshift()mktime() 或()rshift()strftime()strtonum()systime ()xor()函数。

*

本地化的字符串。

*

使用extension()函数动态添加新的内置函数。

AWK书不定义close()函数的返回值。 Gawkclose()函数分别在关闭输出文件或管道时从fclose (3)或pclose (3 返回值。 它在关闭输入管道时返回进程的退出状态。 如果指定的文件,管道或协处理未使用重定向打开,则返回值为-1。

当使用--traditional选项调用gawk时 ,如果-F选项的fs参数为“t”,则FS设置为制表符。 请注意,输入gawk -F \ t ...只会引起shell引用``t'',并且不会将``\ t''传递给-F选项。 由于这是一个相当丑陋的特例,它不是默认行为。 如果已指定--posix,则也不会发生此行为。 要真正获得制表符作为字段分隔符,最好使用单引号: gawk -F'\ t'...。

参见其他命令waitlpcompleteexecvgetfaclioctluniqrmmodpvcreatershunix2doscalfscdiwprivswaponautofstalkmotdfreelprexeclfdiskatwhoiwconfigifconfigvgdisplayopenlsmodntohsmailqkillwtmp