跳转到内容

AWK

25% developed
来自维基教科书,开放书籍,开放世界

本参考手册面向有一定 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,可以在 ezwinportsGnuWin32 项目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];
     } 
   }

链接

普通的 awk 没有内置函数来排序数组。但是,gawk 有 *asort*(按值排序)和 *asorti*(按索引(也称为键)排序)函数。asort 会丢失原始索引,用 1 到 length 索引替换它们。

链接

来自文件的代码

[编辑 | 编辑源代码]

当您在文件中使用 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
  • ...

链接

支持常用的运算符 +、-、*、/、 %、^;gawk 支持 **,但 POSIX awk 不支持。内置数学函数包括 exp、log、sqrt、sin、cos、atan2、rand、srand 和 int。

数字字面量为十进制;在 C 语言风格中,它们可以使用 gawk 中的 GNU 扩展来表示十六进制和八进制。

链接

用户定义的函数

[编辑 | 编辑源代码]

用户定义的函数可以按如下方式定义。

  • 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)}'

链接

位操作

[编辑 | 编辑源代码]

传统的 awk 没有提供位操作的位运算符。但是,gawk 内置了位操作函数,包括 and()、or()、xor()、compl()、lshift() 和 rshift()。

链接

库的包含

[编辑 | 编辑源代码]

传统的 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 库。

链接

单行示例

[编辑 | 编辑源代码]

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 语言中知道的条件运算符的使用。

链接

在线尝试

[编辑 | 编辑源代码]

您可以在 http://awk.js.org/ 上在线尝试 awk。关键词:REPL 在线。

与其他脚本语言相比,AWK 的限制包括以下内容

  • 没有从其他编程语言中知道的数组和列表的直接类似物,只有关联数组。
  • 没有嵌套数组:关联数组的值不能是数组。
  • 没有真正的多维数组:多个索引被存储为通过分隔符连接索引而形成的单个索引。
  • 在普通 awk 中没有用于数组的排序函数,只有在 gawk 中有。
  • 在普通 awk 中没有位运算符;gawk 有位操作函数,包括 and()、or()、compl() 等。
  • 在传统 awk 中不支持包含要由 awk 脚本重用的函数的库或模块;但是,gawk 支持用于该目的的 @include 关键字。
  • 不支持 GUI 编程。

链接

源代码

[编辑 | 编辑源代码]

各种版本的 awk 的源代码

另请参阅

[编辑 | 编辑源代码]
  • O'Reilly 的 sed & awk 袖珍参考
  • UNIX 概览
  • UNIX 力量工具
[编辑 | 编辑源代码]
华夏公益教科书