GAWK(1) 实用程序命令 GAWK(1)
一.名字(NAME)
gawk - 模式扫描和处理语言
二.简介(SYNOPSIS)
gawk [ POSIX or GNU style options ] -f program-file [ -- ] file ...
gawk [ POSIX or GNU style options ] [ -- ] program-text file ...
pgawk [ POSIX or GNU style options ] -f program-file [ -- ] file ...
pgawk [ POSIX or GNU style options ] [ -- ] program-text file ...
dgawk [ POSIX or GNU style options ] -f program-file [ -- ] file ...
三.描述(DESCRIPTION)
Gawk是GNU项目对AWK编程语言的实现。它符合POSIX 1003.1标准中对语言的定义。这个版本反过来是基于Aho、Kernighan和Weinberger用AWK编程语言( The AWK Programming Language)描述的。Gawk提供了在当前UNIX awk的版本和一些特定于GNU的扩展中发现的附加功能。
命令行包含一些选项,包括gawk本身、AWK程序文本(如果不是通过 -f 或 --file选项提供的),以及 预定义的AWK变量ARGC 和 ARGV 中可用的值。
Pgawk是gawk的剖析版。它在所有方面和gawk都是一样的,只是程序运行得更慢,完成后它会在文件awkprof.out中自动生成一个执行配置文件。参见下面的--profile选项。
Dgawk是一个awk调试器。它不是直接运行程序,而是加载AWK源代码,然后提示调试命令。与gawk和pgawk不同,dgawk只处理带有-f选项的AWK程序源代码。调试器记录在GAWK: Effective AWK Programming。
摘录:
awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU 版本。
awk其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。实际上 AWK 的确拥有自己的语言: AWK 程序设计语言 , 三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。
AWK工作流程:
AWK工作流程可分为三个部分:
- 读输入文件之前执行的代码段(由BEGIN关键字标识)。
- 主循环执行输入文件的代码段。
- 读输入文件之后的代码段(由END关键字标识)。
命令结构:
awk 'BEGIN{ commands } pattern{ commands } END{ commands }'
工作流程图如下:
- 1、通过关键字 BEGIN 执行 BEGIN 块的内容,即 BEGIN 后花括号 {} 的内容。
- 2、完成 BEGIN 块的执行,开始执行body块。
- 3、读入有 \n 换行符分割的记录。
- 4、将记录按指定的域分隔符划分域,填充域,$0 则表示所有域(即一行内容),$1 表示第一个域,$n 表示第 n 个域。
- 5、依次执行各 BODY 块,pattern 部分匹配该行内容成功后,才会执行 awk-commands 的内容。
- 6、循环读取并执行各行直到文件结束,完成body块执行。
- 7、开始 END 块执行,END 块可以输出最终结果。
开始块(BEGIN)
语法格式如下:
BEGIN {awk-commands}
开始块就是在程序启动的时候执行的代码部分,并且它在整个过程中只执行一次。
一般情况下,我们可以在开始块中初始化一些变量。
BEGIN 是 AWK 的关键字,因此它必须是大写的。
注意:开始块部分是可选的,你的程序可以没有开始块部分。
主题块(BODY)
语法格式如下:
/pattern/ {awk-commands}
对于每一个输入的行都会执行一次主体部分的命令。
默认情况下,对于输入的每一行,AWK 都会执行命令。但是,我们可以将其限定在指定的模式中。
注意:在主体块部分没有关键字存在。
结束块(END)
语法如下:
END {awk-commands}
结束块是在程序结束时执行的代码。 END 也是 AWK 的关键字,它也必须大写。 与开始块相似,结束块也是可选的。
四.选项格式(OPTION)
Gawk选项可以是传统的POSIX-style的单字母选项,也可以是GNU-style的长选项。POSIX选项以单个“-”开头,而长选项以“--”开头。为特定于GNU的特性和POSIX强制的特性,提供了长选项。
特定于Gawk的选项通常以长选项的形式使用。长选项的参数要么用=符号与该选项连接,中间没有空格,要么在下一个命令行参数中提供它们。Long选项可以缩写,只要缩写保持惟一。
此外,每个长选项都有一个对应的短选项,因此该选项的功能可以从#!可执行脚本内使用。
五.选项(OPTIONS)
Gawk接受以下选项。首先列出标准选项,然后是gawk扩展选项。
-f program-file
--file program-file
从文件program-file中读取AWK程序源代码,而不是从第一个命令行参数中读取。可以使用多个-f(或--file)选项
-F fs
--field-separator fs
使用fs作为输入字段分隔符(预定义变量FS的值)。
-v var=val
--assign var=val
在程序开始执行之前,将val值赋给变量var。这样的变量值可用于一个awk程序的BEGIN块。
-b
--characters-as-bytes
将所有输入数据视为单字节字符。换句话说,当试图将字符串处理为多字节字符时,不要注意语言环境信息。--posix选项覆盖了这个。
-c
--traditional
以兼容模式运行。在兼容模式下,gawk的行为与UNIX awk相同;不识别任何特定于GNU的扩展。有关更多信息,请参见下面的 GNU EXTENSIONS。
-C
--copyright
在标准输出上打印GNU版权信息消息的短版本并成功退出。
-d[file]
--dump-variables[=file]
打印全局变量及其类型和最终值的排序列表到file。如果没有提供file,gawk将在当前目录中使用名为awkvars.out的文件。 拥有所有全局变量的列表是在程序中查找排版错误的好方法。如果您有一个包含许多函数的大型程序,并且您希望确保您的函数不会无意中使用要作为本地变量的全局变量,则也可以使用此选项。(对于i、j等简单的变量名,这是一个特别容易犯的错误。)
-e program-text
--source program-text
使用program-text 作为AWK程序源代码。该选项允许将库函数(通过-f和-file选项使用)与在命令行中输入的源代码轻松地混合在一起。它主要用于shell脚本中使用的大中型AWK程序。
-E file
--exec file
与-f类似,但是,这是最后一个处理的选项。这应该使用于#!脚本,特别是用于CGI应用程序,以避免从URL在命令行上传递选项或源代码(!)。此选项禁用命令行变量赋值。
-g
--gen-pot
扫描和解析AWK程序,并在标准输出上生成一个GNU .pot (可移植对象模板)格式文件,其中包含程序中所有可本地化字符串的条目。程序本身不执行。有关.pot文件的更多信息,请参阅GNU gettext发行版。
-h
--help
-L [value]
--lint[=value]
提供关于可疑或不可移植到其他AWK实现的构造的警告。带有fata的可选参数,lint警告将成为致命错误。这可能是极端的,但它的使用肯定会鼓励开发更干净的AWK程序。如果可选参数为invalid,则只发出关于实际无效的内容的警告。(这还没有完全实现。)
-n
--non-decimal-data
识别输入数据中的八进制和十六进制值。谨慎使用此选项!
-N
--use-lc-numeric
这迫使gawk在解析输入数据时使用本地的小数点字符。虽然POSIX标准要求这种行为,并且gawk在--posix生效时也这样做,但是默认情况下遵循传统行为,并使用句点作为小数点,即使在句点不是小数点字符的地区也是如此。该选项覆盖默认行为,而不具有--posix选项的严格性。
-O
--optimize
对程序的内部表示形式启用优化。目前,这只包括简单的常量折叠。gawk维护者希望随着时间的推移添加额外的优化。
-p[prof_file]
--profile[=prof_file]
将分析数据发送到prof_file。默认值是awkprof.out。当运行gawk时,该配置文件只是程序的“漂亮打印”版本。当使用pgawk运行时,概要文件在左侧空白处包含程序中每个语句的执行计数,以及每个用户定义函数的函数调用计数。
-P
--posix
这将打开兼容模式,并附加以下限制:
1. 无法识别 \x 转义序列。
2. 当FS被设置为单个空格时,只有空格和制表符充当字段分隔符,而换行符则不可以。
3. ? 和 : 后面不能续行。
4. 关键字function的同义词func无法识别。
5. 运算符**和**=不能代替^和^=。
-r
--re-interval
在正则表达式匹配中启用区间表达式(interval expressions)(参见下面的 Regular Expressions)。在AWK语言中,间隔表达式传统上是不可用的。POSIX标准添加了它们,以使awk和egrep保持一致。默认情况下,它们是启用的,但是这个选项仍然与 --traditional一起使用。
-R
--command file
仅限Dgawk命令。从file中读取存储的调试器命令。
-S
-sandbox
以沙箱模式运行gawk,禁用system()函数,使用getline重定向输入,使用print和printf重定向输出,并加载动态扩展。命令执行(通过管道)也被禁用。这可以有效地阻止脚本访问本地资源(命令行中指定的文件除外)。
-t
--lint-old
提供关于 不能移植到Unix awk原始版本的构造 的警告。
-V
--version
在标准输出上打印gawk的这个特定副本的版本信息。这主要是为了了解您的系统上gawk的当前副本是否与自由软件基金会(Free Software Foundation)发布的任何内容相关,是最新的。这在报告bug时也很有用。(根据GNU编码标准,这些选项会导致立即成功退出。)
--
表示选项结束。这有助于允许AWK程序本身的进一步参数以“-”开头。这与大多数其他POSIX程序使用的参数解析约定保持一致。
在兼容模式下,任何其他选项都被标记为无效,但在其他情况下将被忽略。在正常操作中,只要提供了程序文本,就会将未知选项传递给ARGV数组中的AWK程序进行处理。这对于通过#!可执行解释器机制运行AWK程序特别有用。
六.AWK程序执行(AWK PROGRAM EXECUTION)
AWK程序由一系列模式操作语句和可选函数定义组成。
@include "filename" pattern { action statements}
function name(parameter list) { statements}
Gawk首先从program-file(s)(如果指定的话)、从参数到--source或从命令行上的第一个非选项参数读取程序源代码。可以在命令行上多次使用-f和--source选项。Gawk读取程序文本时,就像将所有program-files和命令行源文本连接在一起一样。这对于构建AWK函数库非常有用,而不必将它们包含在使用它们的每个新的AWK程序中。它还提供了将库函数与命令行程序混合的能力。
此外,以@include开头的行可以用于将其他源文件包含到程序中,从而使库的使用更加容易。
环境变量AWKPATH指定了当查找使用-f选项命名的源文件时使用的搜索路径。如果这个变量不存在,默认路径是“.:/usr/local/share/awk”。(实际目录可能有所不同,这取决于gawk是如何构建和安装的。)如果给-f选项的文件名包含“/”字符,则不执行路径搜索。
Gawk按照以下顺序执行AWK程序。首先,执行通过-v选项指定的所有变量赋值。接下来,gawk将程序编译成内部形式。然后,gawk执行BEGIN块(如果有的话)中的代码,然后读取ARGV数组(直到ARGV[ARGC])中命名的每个文件。如果命令行上没有指定文件,gawk将读取标准输入。
如果命令行上的文件名具有var=val格式,则将其视为变量赋值。变量var将被赋值val。(此操作在运行任何BEGIN块之后发生。)命令行变量赋值对于动态地为AWK用于控制输入如何分解为字段和记录的变量赋值是最有用的。如果需要在单个数据文件上进行多次传递,它还可以用于控制状态。
如果ARGV的某个特定元素的值是空的(""),gawk就跳过它。
对于每个输入文件,如果存在一个BEGINFILE规则,gawk在处理文件内容之前执行相关代码。类似地,gawk在处理文件后执行与ENDFILE相关的代码。
对于输入中的每条记录,gawk测试它是否与AWK程序中的任何pattern匹配。对于此记录匹配的每个模式,执行关联的action。按照模式在程序中出现的顺序对它们进行测试。
最后,在所有输入都用完之后,gawk执行END块(如果有的话)中的代码。
-
命令行目录(Command Line Directories)
根据POSIX,在awk命令行上命名的文件必须是文本文件。如果没有定义,则行为是“未定义的”。大多数版本的awk都将命令行上的目录视为致命错误。
七.变量,记录和字段(VARIABLES,RECORDS AND FIELDS)
AWK变量是动态的;当它们第一次被使用时就产生了。它们的值是浮点数或字符串,或者两者都是,这取决于如何使用它们。AWK也有一维数组;可以模拟多维数组。在程序运行时设置几个预定义的变量;这些变量将根据需要进行描述,并在下面进行总结。
-
Records
通常,记录由换行符分隔。您可以通过为内置变量RS赋值来控制记录的分隔方式。如果RS是任何单个字符,那么该字符将分隔记录。否则,RS就是一个正则表达式。与此正则表达式匹配的输入中的文本分隔记录。然而,在兼容模式下,只使用其字符串值的第一个字符来分隔记录。如果RS设置为空字符串,那么记录之间用空行分隔。当RS设置为空字符串时,除了FS可能具有的任何值之外,换行符始终充当字段分隔符。
-
fields
在读取每个输入记录时,gawk使用FS变量的值作为字段分隔符,将记录分割为字段。如果FS是单个字符,则字段由该字符分隔。如果FS是空字符串,那么每个单独的字符就成为一个单独的字段。否则,FS应该是一个完整的正则表达式。在FS是单个空格的特殊情况下,字段由空格和/或制表符和/或换行分隔。(但是请参阅下面POSIX兼容性一节)。注意:IGNORECASE的值(参见下面)还影响到当FS是正则表达式时字段如何分割,当RS是正则表达式时记录如何分割。
如果将FIELDWIDTHS变量设置为以空格分隔的数字列表,则每个字段的宽度都应该是固定的,gawk使用指定的宽度分割记录。忽略FS的值。为FS或FPAT分配新值会覆盖FIELDWIDTHS的使用。
类似地,如果将FPAT变量设置为表示正则表达式的字符串,则每个字段由匹配该正则表达式的文本组成。在本例中,正则表达式描述字段本身,而不是分隔字段的文本。为FS或FIELDWIDTHS分配新值会覆盖FPAT的使用。
输入记录中的每个字段可以由其位置$1、$2等引用。$0是整个记录。字段不需要常量引用:
n = 5
print $n
打印输入记录中的第五个字段。
变量NF被设置为输入记录中字段的总数。
对不存在字段的引用(即$NF之后的字段)会生成空字符串。但是,分配给一个不存在的字段(例如$NF+2= 5)会增加NF的值,创建以null字符串作为值的任何中间字段,并导致重新计算$0的值,字段之间用OFS的值分隔。对负数字段的引用会导致致命错误。递减NF会导致新值之后的字段值丢失,并重新计算$0的值,字段之间用OFS的值分隔。
为现有字段赋值会导致在引用$0时重新生成整个记录。类似地,将值赋给$0会导致重新切分记录,从而为字段创建新值。
-
Built-in Variables(内置变量)
Gawk的内置变量如下:
ARGC 命令行参数的数量(不包括gawk选项或程序源代码)。
ARGIND 正在处理的当前文件的ARGV中的索引。
ARGV 命令行参数数组。数组的索引从0到ARGC - 1。动态更改ARGV的内容可以控制用于数据的文件。
BINMODE 在非posix系统上,指定对所有文件I/O使用“二进制”模式。数值1、2或3分别指定输入文件、输出文件或所有文件应该使用二进制I/O。字符串值“r”或“