AWK
本参考手册面向有一定 UNIX 使用经验的用户,他们可能刚刚遇到问题,并被建议使用 awk 来解决。有关 awk 的更多信息,请参见 An Awk Primer。
以下是主要的 awk 版本:
- awk 或 Bell Labs awk
- nawk 或 new awk
- gawk (GNU awk)
- mawk
nawk 和 gawk 都可以运行 awk 程序,无需修改。
获取 AWK:如果您使用的是 Linux 或 macOS,那么您已经拥有 AWK。对于 MS Windows,可以在 ezwinports、GnuWin32 项目 和 Cygwin 中找到 GNU awk 的版本。
Awk 从文件或标准输入读取数据,并将结果输出到标准输出。您通常希望将结果重定向到文件,但这些示例中没有这样做,因为这样会占用空间。awk 不适用于非文本文件,例如可执行文件和 FrameMaker 文件。如果您需要编辑这些文件,请使用二进制编辑器,例如 emacs 中的 hexl-mode。
学习 awk 令人沮丧的一点是,要让您的程序通过 shell 的解析器。正确的方法是在程序周围使用单引号,如下所示
>awk '{print $0}' filename
单引号保护几乎所有内容免受 shell 的影响。在 csh 或 tcsh 中,您仍然需要注意感叹号,但除此之外,您是安全的。
学习 awk 令人沮丧的另一点是可爱的错误信息
awk '{print $0,}' filename awk: syntax error near line 1 awk: illegal statement near line 1
gawk 通常有更好的错误信息。至少它会告诉你哪里出错了
gawk '{print $0,}' filename gawk: cmd. line:1: {print $0,} gawk: cmd. line:1: ^ parse error
因此,如果您在获取 awk 语法方面遇到问题,请暂时切换到 gawk。
- Awk 识别“文件”、“记录”和“字段”的概念。
- 文件由记录组成,默认情况下,记录是文件的行。一行成为一条记录。
- Awk 一次处理一条记录。
- 记录由字段组成,默认情况下,字段由任意数量的空格或制表符分隔。
- 字段 1 使用 $1 访问,字段 2 使用 $2 访问,依此类推。$0 指的是整个记录。
学习 awk 的最快方法可能是查看一些示例程序。上面的示例程序将打印整个文件,就像 cat(1) 一样。以下是一些其他示例,以及对它们功能的简要说明。
>awk '{print $2,$1}' filename
将打印第二个字段,然后是第一个字段。所有其他字段将被忽略。
>awk '{print $1,$2,sin($3/$2)}' filename
将打印第一个和第二个字段,然后是第三个字段除以第二个字段的正弦值。因此,第二个和第三个字段最好是数字。Awk 有其他内置的数学函数,例如正弦;阅读手册页以查看哪些函数可用。
- "我仍然经常说 awk '{print $1}'."
- PERL 的发明者 Larry Wall ([email protected])
如果您不想将程序应用于文件的每一行,该怎么办?例如,您可能只想处理第一个字段大于第二个字段的行。以下程序可以做到这一点
>awk '$1 > $2 {print $1,$2,$1-$2}' filename
花括号之外的部分称为“模式”,花括号内部的部分称为“动作”。比较运算符包括来自 C 的运算符
== != < > <= >= ?:
如果没有给出模式,则动作将应用于所有行。上面示例程序中使用了此事实。如果没有给出动作,则将打印整行。如果“print”单独使用,则将打印整行。因此,以下几种方法是等效的
awk '$1 > $2' filename awk '$1 > $2{print}' filename awk '$1 > $2{print $0}' filename
一行中的各个字段也可以被视为字符串而不是数字。要将字段与字符串进行比较,请使用以下方法
> awk '$1=="foo"{print $2}' filename
如果您想要包含特定字符串的行,只需在模式中添加一个 正则表达式(与 egrep(1) 类似),如下所示
>awk '/foo.*bar/{print $1,$3}' filename
这将打印包含单词“foo”的所有行,然后打印包含单词“bar”的所有行。如果您只想打印第二个字段中包含“foo”的行,请使用 ~(“包含”)运算符
>awk '$2~/foo/{print $3,$1}' filename
如果您想要打印第二个字段中不包含“foo”的行,请使用否定 ~ 运算符,!~
>awk '$2!~/foo/{print $3,$1}' filename
这个运算符可以理解为“不包含”。
您可以使用来自 C 的布尔运算符创建复杂的模式,这些运算符包括!用于“非”,&& 用于“与”,|| 用于“或”。可以使用括号进行分组。
模式有三种特殊形式,它们不符合上述描述。其中之一是正则表达式的起始-结束对。例如,要打印包含“foo”和“bar”的所有行,包括它们本身,可以使用以下代码
>awk '/foo/,/bar/' filename
另外两种特殊形式与此类似;它们是 BEGIN 和 END 模式。与 BEGIN 模式关联的任何动作将在执行任何逐行处理之前发生。与 END 模式关联的动作将在处理完所有行后发生。
但是,如何将多个模式-动作对放入一个 awk 程序中?有多种选择。其中之一是将它们合并在一起,如下所示
> awk 'BEGIN{print"fee"} $1=="foo"{print"fi"} END{print"fo fum"}' filename
另一种选择是将程序放入一个文件中,如下所示
BEGIN{print"fee"} $1=="foo"{print"fi"} END{print"fo fum"}
假设该文件名为 giant.awk。现在,使用 awk 的“-f”标志运行它
> awk -f giant.awk filename
第三种选择是创建一个调用 awk 的文件。以下形式可以做到这一点
#!/usr/bin/awk -f BEGIN{print"fee"} $1=="foo"{print"fi"} END{print"fo fum"}
如果我们调用此文件 giant2.awk,我们可以通过首先授予它执行权限来运行它,
> chmod u+x giant2.awk
然后像这样调用它
> ./giant2.awk filename
awk 有变量,这些变量可以是实数或字符串。例如,以下代码打印第五列的运行总计
> awk '{print x+=$5,$0 }' filename
这在查看“ls -l”中的文件大小时很有用。在核对账单时,如果支票金额保留在一列中,它也很有用。
awk 变量在第一次使用时被初始化为零或空字符串。当然,具体情况取决于它们的使用方式。
变量对于保存中间值也很有用。此示例还介绍了使用分号来分隔语句
> awk '{d=($2-($1-4));s=($2+$1);print d/sqrt(s),d*d/s }' filename
请注意,最后一个语句(在本例中是“print”)不需要分号。尽管如此,加入分号也不会造成伤害。
- 整数变量可以用来引用字段。如果一个字段包含有关哪个其他字段重要的信息,此脚本将只打印重要的字段
> awk '{imp=$1; print $imp }' filename
- 特殊变量 NF 会告诉您这条记录中有多少个字段。此脚本打印每条记录的第一个和最后一个字段,无论有多少个字段
> awk '{print $1, $NF}' filename
- 特殊变量 NR 会告诉您这是第几条记录。每读取一条新记录,它都会递增一次。这提供了一种简单的方法为文件添加行号
> awk '{print NR, $0}' filename
当然,还有无数其他方法可以使用各种 UNIX 工具为文件添加行号。这留作练习,供读者自行完成。
- 特殊变量 FS(字段分隔符)决定了 awk 如何将每条记录分割成字段。此变量可以在命令行中设置。例如,/etc/passwd 的字段用冒号分隔。
> awk -F: '{print $1,$3 }' /etc/passwd
- 此变量实际上可以设置为任何正则表达式,与 egrep(1) 类似。
各个字段也是变量,您可以将内容赋给它们。如果您想删除每行中的第 10 个字段,您可以通过使用 for 循环打印字段 1 到 9,然后从 11 开始打印(见下文)来实现。但这将非常轻松地完成。
> awk '{$10=""; print }' filename
在很多方面,awk 类似于 C。它包含所有 "for"、"while"、"do-while" 和 "if" 结构。语句可以用大括号分组。此脚本将在自己的行上打印每个记录的每个字段。
> awk '{for(i=1;i<=NF;i++) print $i }' filename
如果您想生成比 "print" 语句提供的格式更好格式的格式,您可以像在 C 中一样使用 "printf"。以下是一个示例,它将第一个字段视为字符串,然后进行一些数字操作。
> awk '{printf("%s %03d %02d %.15g\n",$1,$2,$3,$3/$2); }' filename
使用 printf,您需要显式的换行符。
我们可以使用 "printf" 打印不带换行符的内容,这对于以每行一个记录的顺序反向打印记录字段很有用。
> awk '{for(i=NF;i > 0;i--) printf("%s",$i); printf("\n"); }' filename
awk 有关联数组,由字符串索引。它没有 C 语言数组的直接类似物。字符串索引的关联数组本身很有用,但让它们像普通数组一样工作很麻烦。
例如,我们可以统计文档中单词的频率(忽略打印它们的令人讨厌的部分)。
> awk '{for(i=1;i <=NF;i++) freq[$i]++ }' filename
该数组将为文件中出现的每个单词保存一个整数值。不幸的是,这将把 "foo"、"Foo" 和 "foo," 视为不同的单词。好吧。我们如何打印出这些频率?awk 有一个特殊的 "for" 结构,用于遍历数组中的值。此脚本比大多数命令行都长,因此它将表示为可执行脚本。
#!/usr/bin/awk -f {for(i=1;i <=NF;i++) freq[$i]++ } END{for(word in freq) print word, freq[word] }
此遍历数组的循环似乎没有特定的顺序。因此,来自此类程序的输出通常必须通过 sort(1) 进行管道传输才能有用。
多维数组以一种奇怪的方式实现。给定的索引将一起连接(使用一个特殊的分隔符)以获得一个字符串,并将其用作索引。此程序将打印单词对的频率。
#!/usr/bin/awk -f {for(i=1;i < NF;i++) freq[$i,$(i+1)]++ } END{for(words in freq) print words, freq[words] }
不幸的是,这将打印出分隔符,该分隔符默认情况下不是常用字符。您可以通过使用 nawk 或 gawk 将像空格这样的逻辑内容分配给变量 SUBSEP 来更改此问题(在普通 awk 中不允许这样做)。
#!/usr/bin/awk -f BEGIN{SUBSEP=""} {for(i=1;i < NF;i++) freq[$i,$(i+1)]++} END{for(words in freq) print words, freq[words] }
不幸的是,这不能让您单独引用索引。这里的秘诀是使用 "split" 函数,它将字符串分解成一个数组。
#!/usr/bin/awk -f BEGIN{SUBSEP="" } {for(i=1;i < NF;i++) freq[$i,$(i+1)]++} END{ for(words in freq) { split(words,word,SUBSEP); print word[1], freq[words],word[2]; } }
链接
- 8 Arrays in awk in The GNU Awk User’s Guide, gnu.org
普通的 awk 没有内置函数来排序数组。但是,gawk 有 *asort*(按值排序)和 *asorti*(按索引(也称为键)排序)函数。asort 会丢失原始索引,用 1 到 length 索引替换它们。
链接
- 12.2.2 Sorting Array Values and Indices with gawk in The GNU Awk User’s Guide, gnu.org
当您在文件中使用 awk 脚本时,可以将程序分成多行,以使其更易于阅读。注释以与 sh 编程相同的方式开头,使用 #。
#!/usr/bin/awk -f # this program prints the frequencies of word pairs BEGIN{SUBSEP=""} # set the index separator # to a nice character {for(i=1;i < NF;i++) freq[$i,$(i+1)]++} END{ for(words in freq) { # just to show we can put a comment in here. split(words,word,SUBSEP); # or here print word[1], freq[words],word[2]; } }
您可以使用 awk 创建文本,以及处理现有文本。它对于快速生成函数值表非常有用,无需编译 C 程序。例如,它可以显示 sin(x)/x 随着 x 接近零而接近 1。
> awk '{x=1.0/NR; print x,sin(x)/x;}'
每次读取新行时都会打印一个新值。因此,您可以按回车键,直到获得所需的所有值。或者,如果您需要一定数量的值,您可以执行以下操作:
> awk 'BEGIN{for(i=1;i <=30;i++){x=1.0/i;print x,sin(x)/x;}}' /dev/null
其中 30 是设定值的数量。
- {} : 用于操作周围,以及在操作中分组语句。
- $ : 表示字段。$1 是第一个字段,$0 是整个记录。
- ~ : "包含" 操作符。 "foobar"~"foo" 为真。仅限字符串。
- !~ : "不包含" 操作符。仅限字符串。
- == : 等于操作符。适用于数字或字符串。
- < > <= >= != : 不等式操作符。适用于数字或字符串。
- # : 注释开始字符。
- , : 在 "print" 或 "printf" 语句中分隔项目。
- ; : 分隔语句。
- // : 用于正则表达式周围。
- && : 布尔与。
- || : 布尔或。
- ! : 布尔非。
- () : 用于对布尔表达式进行分组,向函数传递参数,以及在 "for"、"while" 等等的条件周围。
Awk 可用于生成不想手工输入的 C 代码。例如,此脚本将生成显式 3x3 矩阵乘法例程。
gawk 'BEGIN{ for(i=0;i<3;i++) for(j=0;j<3;j++){ printf("d[%d][%d]=",i,j); for(k=0;k<3;k++){ printf("l[%d][%d]*r[%d][%d]%s", i,k,k,j,(k<2)?"+":";\n"); } } }'
现在来看一个大型示例。
# This awk program collects statistics on two # "random variables" and the relationships # between them. It looks only at fields 1 and # 2 by default Define the variables F and G # on the command line to force it to look at # different fields. For example: # awk -f stat_2o1.awk F=2 G=3 stuff.dat \ # F=3 G=5 otherstuff.dat # or, from standard input: # awk -f stat_2o1.awk F=1 G=3 # It ignores blank lines, lines where either # one of the requested fields is empty, and # lines whose first field contains a number # sign. It requires only one pass through the # data. This script works with vanilla awk # under SunOS 4.1.3. BEGIN{ F=1; G=2; } length($F) > 0 && \ length($G) > 0 && \ $1 !~/^#/ { sx1+= $F; sx2 += $F*$F; sy1+= $G; sy2 += $G*$G; sxy1+= $F*$G; if( N==0 ) xmax = xmin = $F; if( xmin > $F ) xmin=$F; if( xmax < $F ) xmax=$F; if( N==0 ) ymax = ymin = $G; if( ymin > $G ) ymin=$G; if( ymax < $G ) ymax=$G; N++; } END { printf("%d # N\n" ,N ); if (N <= 1) { printf("What's the point?\n"); exit 1; } printf("%g # xmin\n",xmin); printf("%g # xmax\n",xmax); printf("%g # xmean\n",xmean=sx1/N); xSigma = sx2 - 2 * xmean * sx1+ N*xmean*xmean; printf("%g # xvar\n" ,xvar =xSigma/ N ); printf("%g # xvar unbiased\n",xvaru=xSigma/(N-1)); printf("%g # xstddev\n" ,sqrt(xvar )); printf("%g # xstddev unbiased\n",sqrt(xvaru)); printf("%g # ymin\n",ymin); printf("%g # ymax\n",ymax); printf("%g # ymean\n",ymean=sy1/N); ySigma = sy2 - 2 * ymean * sy1+ N*ymean*ymean; printf("%g # yvar\n" ,yvar =ySigma/ N ); printf("%g # yvar unbiased\n",yvaru=ySigma/(N-1)); printf("%g # ystddev\n" ,sqrt(yvar )); printf("%g # ystddev unbiased\n",sqrt(yvaru)); if ( xSigma * ySigma <= 0 ) r=0; else r=(sxy1 - xmean*sy1- ymean * sx1+ N * xmean * ymean) /sqrt(xSigma * ySigma); printf("%g # correlation coefficient\n", r); if( r > 1 || r < -1 ) printf("SERIOUS ERROR! CORRELATION COEFFICIENT"); printf(" OUTSIDE RANGE -1..1\n"); if( 1-r*r != 0 ) printf("%g # Student's T (use with N-2 degfreed)\n&", \ t=r*sqrt((N-2)/(1-r*r)) ); else printf("0 # Correlation is perfect,"); printf(" Student's T is plus infinity\n"); b = (sxy1 - ymean * sx1)/(sx2 - xmean * sx1); a = ymean - b * xmean; ss=sy2 - 2*a*sy1- 2*b*sxy1 + N*a*a + 2*a*b*sx1+ b*b*sx2 ; ss/= N-2; printf("%g # a = y-intercept\n", a); printf("%g # b = slope\n" , b); printf("%g # s^2 = unbiased estimator for sigsq\n",ss); printf("%g + %g * x # equation ready for cut-and-paste\n",a,b); ra = sqrt(ss * sx2 / (N * xSigma)); rb = sqrt(ss / ( xSigma)); printf("%g # radius of confidence interval "); printf("for a, multiply by t\n",ra); printf("%g # radius of confidence interval "); printf("for b, multiply by t\n",rb); }
此文档最初由 Andrew M. Ross 编写。它可以在这里找到 here 并且由哈维穆德学院计算机科学系根据 GFDL 发布。
awk 的命令行选项(也称为开关)。
- -F field-separator: 使用字段分隔符正则表达式来分隔字段。
- -f source-file
- -v var=val: 将变量设置为该值。由 POSIX 定义;在原始 awk 中不存在。
GNU awk 的命令行选项(也称为开关),超出基本 awk。
- -W gawk-opt
- ...
- --posix
- ...
链接
- 2.2 Command-Line Options in The GNU Awk User's Guide, gnu.org
- Unix awk(1) manual page at man.cat-v.org
支持常用的运算符 +、-、*、/、 %、^;gawk 支持 **,但 POSIX awk 不支持。内置数学函数包括 exp、log、sqrt、sin、cos、atan2、rand、srand 和 int。
数字字面量为十进制;在 C 语言风格中,它们可以使用 gawk 中的 GNU 扩展来表示十六进制和八进制。
链接
- 6.2.1 Arithmetic Operators in The GNU Awk User’s Guide, gnu.org
- 9.1.2 Numeric Functions in The GNU Awk User’s Guide, gnu.org
用户定义的函数可以按如下方式定义。
- function plus(x,y) { return x+y }
一些 awk 实现(包括 gawk)允许使用 "func" 代替 "function",但这不符合 POSIX 标准。
支持递归。
- awk 'function fact(x) { if (x > 1) { return x*fact(x-1) } else return 1} BEGIN{print fact(4)}'
链接
- 9.2 User-Defined Functions in The GNU Awk User’s Guide, gnu.org
- User-Defined Functions in awk, opengroup.org
传统的 awk 没有提供位操作的位运算符。但是,gawk 内置了位操作函数,包括 and()、or()、xor()、compl()、lshift() 和 rshift()。
链接
- GNU Awk 用户指南中的位操作函数,gnu.org
传统的 awk 没有办法在 awk 程序中包含或导入函数库;最接近的方法是多次使用 -f 选项。相比之下,gawk 提供了这种可能性作为 GNU 扩展,使用 @include 关键字。
只要库文件所在的目录在 AWKPATH 环境变量中,就不需要指定库文件的完整路径。设置 AWKPATH 会阻止 awk 将当前目录视为路径的一部分,除非 AWKPATH 包含句点 (.) 来表示当前目录。AWKPATH 的项目分隔符是冒号 (:),或者在 Windows 上是分号 (;)。
也可以通过 gawk 的 -i 选项加载 awk 函数库。因此,如果您有文件 lib.awk,该文件目录的路径在 AWKPATH 中,并且该文件定义了 abs 函数,您可以像这样调用 gawk
- awk -ilib "BEGIN {print abs(-4)}"
您无法使用 -f 选项执行此操作;您必须将主程序存储在单独的文件中,然后在同一命令行上两次使用 -f 选项,第一次加载库,第二次加载主程序。
可以在 Github 上的 Many AWK 项目中找到许可证宽松的 awk 库。
链接
- 2.7 将其他文件包含到您的程序中,GNU Awk 用户指南,gnu.org
- 2.5.1 AWKPATH 环境变量,GNU Awk 用户指南,gnu.org
- 2.2 命令行选项,GNU Awk 用户指南,gnu.org
- 10 awk 函数库,GNU Awk 用户指南,gnu.org
- Many AWK - awk 函数库 (MIT 许可证),github.com
- awk-libs - awk 函数库,github.com
awk 使用的单行示例
- echo abcd |awk '/b.*d/'
- 输出与正则表达式匹配的行,类似于 grep 命令。
- echo abcd |awk '/b.*d/ {print $0}'
- 与上面相同,使用显式 print 语句。$0 代表整行。
- echo ab cd |awk '/b.*d/ {print $2}'
- 对于与正则表达式匹配的行,输出第二个字段。默认情况下,使用一系列空格作为字段分隔符。因此,输出 "cd"。
- echo abcd,e |awk -F, '/b.*d/ {print $2}'
- 对于与正则表达式匹配的行,输出第二个字段,由于 -F 选项,使用逗号作为字段分隔符。因此,输出 "e"。
- echo abcd,e |awk '{print toupper($0)}'
- 输出所有大写字母的行。对于小写字母,使用 "tolower"。
- echo a b c d | awk '{print $NF, $(NF-1)}'
- 输出最后一个字段和倒数第二个字段;NF 是字段数。
- echo ab cd | awk 'NF>=2'
- 输出字段数为 2 或更多的行。
- echo ab cd | awk '{print NF}'
- 对于每一行,输出其中的字段数。
- echo ab cd | awk 'length($2) > 1'
- 输出所有第二字段长度大于 1 的行。
- echo ab cd | awk '$2 ~ /cd/'
- 输出第二字段与正则表达式匹配的所有行。
- echo ab cd | awk '$1 ~ /ab/ && $2 ~ /cd/'
- 与上面类似,但有两个子条件用 "&&" 连接。支持从 C 编程语言中知道的其他一些逻辑运算符。
- cat file.txt | awk 'NR >= 100 && NR <= 500'
- 输出行号在指定范围内的行(记录)。因此,充当行号过滤器。
- cat file.txt | awk 'NR == 1 || /reg.*pattern/'
- 输出第一行和与正则表达式匹配的行。
- echo abcd | awk '{gsub(/ab/,"ef");print}'
- 替换,也称为替换,类似于 sed 命令;gsub 中的 "g" 代表全局。
- awk 'BEGIN{for(i=1;i<6;i++) print sqrt(i)}'
- 输出 1、...、5 中整数的平方根。使用 BEGIN{} 确保代码无论是否有输入行被馈送到 awk 都被执行。for 循环使用熟悉的 C 语言语法,sqrt 是多个可用数学函数之一。
- awk 'BEGIN{printf "%i %.2f\n", 1, (2+3)/7}'
- 支持从 C 语言中熟悉的 printf 函数,作为不需要围绕参数的括号的语句。
- awk 'BEGIN{for(i=1;i<9;i++) a[i]=i^2; for(i in a) print i, a[i]}'
- 在 awk 关联数组(也称为映射或字典)的帮助下,输出几个整数及其平方。输出的顺序是不确定的,这在关联数组中很常见。Awk 没有从其他编程语言中知道的数组和列表的直接类似物。
- cat file.txt | awk '{sum+=$1} END{print sum}'
- 使用 END 关键字输出第一个字段(列)中值的总和。
- printf 1,2,3\\n4,5,6 | awk -F, '{s=0;for(i=1; i<=NF; i++) {s+=$i} print s}'
- 对于逗号分隔文件中的每一行,输出该行中字段(列)的总和。因此,遍历字段。
- echo 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 | awk -F, -vn=7 '{for(i=1;i<=NF; i++) {s+=i>n?$i-$(i-n):$i; if(i>=n){printf "%.0f, ", s/n}else{printf ", "}}}'
- 输出逗号分隔输入逗号分隔序列的 7 值简单移动平均值。
- awk 'BEGIN{system("dir")}'
- 运行外部命令 dir;在沙箱模式下禁用。
- awk 'function abs(x) {return x < 0 ? -x : x} BEGIN{print abs(-4)}'
- 定义并使用绝对值函数。展示了从 C 语言中知道的条件运算符的使用。
链接
- 有用的“单行命令”,AWK 手册,第 1.0 版,staff.science.uu.nl
- awk per POSIX,“示例”部分,opengroup.org
- AWK 的便捷单行命令,catonmat.net
您可以在 http://awk.js.org/ 上在线尝试 awk。关键词:REPL 在线。
与其他脚本语言相比,AWK 的限制包括以下内容
- 没有从其他编程语言中知道的数组和列表的直接类似物,只有关联数组。
- 没有嵌套数组:关联数组的值不能是数组。
- 没有真正的多维数组:多个索引被存储为通过分隔符连接索引而形成的单个索引。
- 在普通 awk 中没有用于数组的排序函数,只有在 gawk 中有。
- 在普通 awk 中没有位运算符;gawk 有位操作函数,包括 and()、or()、compl() 等。
- 在传统 awk 中不支持包含要由 awk 脚本重用的函数的库或模块;但是,gawk 支持用于该目的的 @include 关键字。
- 不支持 GUI 编程。
链接
- C.4 可能的未来扩展,GNU Awk 用户指南,适用于 gawk 3.1.0,gnu.org
各种版本的 awk 的源代码
- Brian Kernighan 的 awk,带有一些额外的修复,如 onetrueawk/awk,github.com;克隆是 arnoldrobbins/bwk-awk
- Mike Brennan 的 mawk-2,github.com
- Thomas Dickey 的 mawk 版本,github.com
- gawk,git.savannah.gnu.org
- O'Reilly 的 sed & awk 袖珍参考
- UNIX 概览
- UNIX 力量工具
- GNU Awk 用户指南,gnu.org
- awk 手册页,freebsd.org
- Unix awk(1) manual page at man.cat-v.org
- awk POSIX 规范,opengroup.org
- 维基百科:AWK
- AWK 入门,cs.hmc.edu,此维基教科书的原始来源
- 33.11 快速参考:awk,Peek、O'Reilly & Loukides 编著的 Unix Power Tools,docstore.mik.ua
- 类别:AWK,rosettacode.org
- comp.lang.awk,groups.google.com
- 在 Y 分钟内学习 X,其中 X=awk,learnxinyminutes.com
- Awk 编程语言 (1988) [pdf] 来自 archive.org