跳转到内容

Awk 入门/Awk 程序示例

来自维基教科书,开放的书籍,开放的世界

一个大型程序

[编辑 | 编辑源代码]

这一切都很有趣,但这些例子似乎只在“coins.txt”上做一些小的改动。为什么不让 Awk 一次性找出所有有趣的东西呢?

这个想法的直接反对意见是,在命令行上输入大量的 Awk 语句会很麻烦,但这个问题很容易解决。这些命令可以写入一个文件,然后 Awk 可以从该文件执行命令。

awk -f awk program file name

有了以这种方式编写 Awk 程序的能力,那么“主”“coins.txt”分析程序应该做什么呢?这里是一个可能的输出

Summary Data for Coin Collection:

    Gold pieces:                   nn
    Weight of gold pieces:         nn.nn
    Value of gold pieces:        nnnn.nn

    Silver pieces:                 nn 
    Weight of silver pieces:       nn.nn
    Value of silver pieces:      nnnn.nn

    Total number of pieces:        nn  
    Value of collection:         nnnn.nn

“主”程序

[编辑 | 编辑源代码]

以下 Awk 程序生成此信息

# This is an awk program that summarizes a coin collection.
/gold/    { num_gold++; wt_gold += $2 }                           # Get weight of gold.
/silver/  { num_silver++; wt_silver += $2 }                       # Get weight of silver.
END {
    val_gold = 485 * wt_gold;                                     # Compute value of gold.
    val_silver = 16 * wt_silver;                                  # Compute value of silver. 
    total = val_gold + val_silver;

    print "Summary data for coin collection:";
    printf("\n");                                                 # Skips to the next line.
    printf("    Gold pieces:\t\t%4i\n", num_gold);
    printf("    Weight of gold pieces:\t%7.2f\n", wt_gold);
    printf("    Value of gold pieces:\t%7.2f\n", val_gold);
    printf("\n");
    printf("    Silver pieces:\t\t%4i\n", num_silver);
    printf("    Weight of silver pieces:\t%7.2f\n", wt_silver);
    printf("    Value of silver pieces:\t%7.2f\n", val_silver);
    printf("\n");
    printf("    Total number of pieces:\t%4i\n", NR);
    printf("    Value of collection:\t%7.2f\n", total);
}

此程序有一些有趣的功能

  • 可以使用 # 在程序中插入注释。Awk 忽略 # 之后的任何内容。
  • 请注意语句 num_gold++num_silver++。C 程序员应该了解 ++ 运算符;不了解的人可以放心,它只是将指定的变量增加 1。还有一个 -- 用于递减变量。
  • 可以使用分号 (;) 将多条语句写在同一行。如果一行只有一条语句,分号是可选的。
  • 请注意 printf 语句的使用,它提供了比 print 语句更灵活的打印功能。
printf 语句

printf 的一般语法如下

printf("<format_code>", <parameters>)

特殊字符:

  • \n 换行
  • \t 制表符(对齐间距)

格式代码:

  • %i%d 整数
  • %f 浮点数(十进制)
  • %s 字符串

以上对 printf 的描述过于简化。还有许多其他代码和选项,将在后面讨论。

列表中的每个参数都有一个格式代码。每个格式代码决定其对应参数将如何打印。例如,格式代码 %2d 告诉 Awk 打印一个两位数的整数,格式代码 %7.2f 告诉 Awk 打印一个七个字符的浮点数,包括小数点右边两位数。小数点算作七个字符之一。

还要注意,在这个例子中,printf 打印的每个字符串都以 \n 结尾,这是一个换行 代码(ASCII 换行符代码)。与 print 语句不同,print 语句在打印一行时会自动将输出移到下一行,printf 不会自动移到下一行,默认情况下,下一个输出语句会将其输出附加到同一行。换行符会强制输出跳到下一行。

\t 创建的制表符将输出对齐到最接近的制表位,通常是 8 个空格。制表符对于创建表格和整齐对齐的输出很有用。

运行程序

[编辑 | 编辑源代码]

我把这个程序存储在一个名为“summary.awk”的文件中,并按以下方式调用它

awk -f summary.awk coins.txt

输出是

Summary data for coin collection:

    Gold pieces:		   9
    Weight of gold pieces:	   6.10
    Value of gold pieces:	2958.50

    Silver pieces:		   4
    Weight of silver pieces:	  12.50
    Value of silver pieces:	 200.00

    Total number of pieces:	  13
    Value of collection:	3158.50

到目前为止,你已经掌握了足够的信息来有效地使用 Awk。下一章将对该语言进行更完整的描述。

  1. 修改上面的程序,统计并显示“coins.txt”中的国家。
  2. 编写一个程序,统计并显示空白行和非空白行的数量(使用 NF)。
  3. 修改程序 #2,计算每行的平均单词数。
华夏公益教科书