跳转到内容

Awk 入门/从命令行使用 Awk

来自维基教科书,为开放世界提供开放书籍

Awk 编程语言的设计目标是简单但功能强大。它允许用户通过在命令行上编写的 Awk 程序执行相对复杂的文本操作。

例如,假设我想将单倍行距的文档转换为双倍行距的文档。我可以使用以下 Awk 程序轻松实现这一点

   awk '{print ; print ""}' infile > outfile

请注意,单引号 (' ') 用于在 Awk 表达式中使用双引号 (" ")。这会将特殊字符隐藏起来,防止 shell 解释它们。我们也可以这样做

   awk "{print ; print \"\"}" infile > outfile 

— 但单引号方法更简单。

这个程序按照预期执行了操作,但它也使输入文件中的每个空行都加倍,这会在输出中留下很多空白。这个问题很容易解决,只需告诉 Awk 如果当前行不是空行,则打印额外的空行即可

   awk '{print ; if (NF != 0) print ""}' infile > outfile
  • Awk 的一个问题是它足够巧妙,会让用户想尝试它,并将其用于它并不真正适合的任务。例如,我们可以使用 Awk 来计算文件中行的数量
   awk 'END {print NR}' infile

— 但这样做很笨拙,因为 “wc (字数统计)” 实用程序可以更轻松地获得相同的结果:”使用合适的工具完成任务”。

Awk 是处理稍微复杂的任务的合适工具。我曾经有一个包含电子邮件分发列表的文件。文件中不同组的电子邮件地址位于连续行上,不同组之间用空行隔开。如果我想快速可靠地确定分发列表中有多少人,我无法使用 “wc”,因为它会统计空行,但 Awk 可以轻松解决这个问题

   awk 'NF != 0 {++count} END {print count}' list
  • 我遇到的另一个问题是确定多个文件的大小平均值。我使用扫描仪创建了一组位图,并将它们存储在磁盘上。磁盘开始满了,我很好奇还能在磁盘上存储多少位图。

我可以使用 “wc -c” 或 “list” 实用程序 (“ls -l” 或 “ll”) 获取以字节为单位的文件大小。几次测试表明 “ll” 速度更快。由于 “ll”

在第五个字段中列出文件大小,我只需要将第五个字段的总和除以 NR。然而,存在一个细微的问题:”ll” 输出的第一行列出了使用的扇区总数,需要跳过它。

没问题。我只需输入

   ll | awk 'NR!=1 {s+=$5} END {print "Average: " s/(NR-1)}'

这给了我大约每文件 40 KB 的平均值。

  • Awk 对于执行简单迭代计算非常有用,而对于更复杂的语言(如 C)来说,这可能过于繁琐。考虑一下斐波那契数列
   1 1 2 3 5 8 13 21 34 ...

序列中的每个元素都是通过将前两个元素相加得到的,前两个元素都定义为 “1”。这是指数增长的离散公式。使用 Awk 生成这个序列非常容易

   awk 'BEGIN {a=1;b=1; while(++x<=10){print a; t=a;a=a+b;b=t}; exit}'

这将生成以下输出数据

   1    2    3    5    8    13    21    34    55    89
华夏公益教科书