跳转到内容

Awk 入门/使用 print 和 printf 进行输出

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

最简单的输出语句是现在熟悉的 "print" 语句。它很简单

  • "Print" 本身会打印输入行。
  • "Print" 带一个参数会打印该参数。
  • "Print" 带多个参数会打印所有参数,参数之间用空格(或其他指定的 OFS)分隔,或者当参数之间用空格分隔时,参数会连接在一起。

"printf()"(格式化打印)函数更加灵活,也更难懂。它的语法如下

   printf(<string>,<expression list>)

"string" 可以是普通的字符字符串

   printf("Hi, there!")

这会将 "Hi, there!" 打印到显示器,就像 "print" 一样,只有一点不同:光标会停留在文本末尾,而不是像 "print" 一样跳到下一行。必须添加一个 "换行" 代码 ("\n") 才能强制 "printf()" 跳到下一行。

   printf("Hi, there!\n")

到目前为止,"printf()" 看起来像是 "print" 的倒退,对于像这样简单的事情,它确实是。但是,当需要对输出的外观进行精确控制时,"printf()" 就很有用。诀窍是字符串可以包含格式或 "转换" 代码来控制表达式列表中表达式的结果。例如,以下程序

   BEGIN {x = 35; printf("x = %d decimal, %x hex, %o octal.\n",x,x,x)}

—打印

   x = 35 decimal, 23 hex, 43 octal.

本例中的格式代码包括:"%d"(指定十进制输出)、"%x"(指定十六进制输出)和 "%o"(指定八进制输出)。"printf()" 函数将表达式列表中的三个变量替换为这些格式代码进行输出。

  • 格式代码非常灵活,它们的用法可能有点混乱。格式代码 "d" 会以十进制格式打印数字。输出是一个整数,即使数字是实数,比如 3.14159。尝试使用此格式代码打印字符串会导致输出为 "0"。例如
   x = 35;     printf("x = %d\n",x)      # yields:  x = 35    
   x = 3.1415; printf("x = %d\n",x)      # yields:  x = 3    
   x = "TEST"; printf("x = %d\n",x)      # yields:  x = 0
  • 格式代码 "o" 会以八进制格式打印数字。除此之外,此格式代码的行为与 "%d" 格式说明符完全相同。例如
   x = 255; printf("x = %o\n",x)          # yields:  x = 377
  • 格式代码 "x" 会以十六进制格式打印数字。除此之外,此格式代码的行为与 "%d" 格式说明符完全相同。例如
   x = 197; printf("x = %x\n",x)          # yields:  x = c5
  • 格式代码 "c" 会打印字符,给出其数字代码。例如,以下语句会输出所有可打印字符
   BEGIN {for (ch=32; ch<128; ch++) printf("%c   %c\n",ch,ch+128)}
  • 格式代码 "s" 会打印字符串。例如
   x = "jive"; printf("string = %s\n",x)  # yields:  string = jive
  • 格式代码 "e" 会以指数格式打印数字,采用默认格式
   [-]D.DDDDDDe[+/-]DDD

例如

   x = 3.1415; printf("x = %e\n",x)       # yields:  x = 3.141500e+000
  • 格式代码 "f" 会以浮点格式打印数字,采用默认格式
   [-]D.DDDDDD

例如

   x = 3.1415; printf("x = %f\n",x)       # yields:  f = 3.141500
  • 格式代码 "g" 会以指数或浮点格式打印数字,选择最短的格式。
  • 可以在 "%" 和格式代码之间插入一个数字字符串,以指定对输出格式的更多控制。例如
   %3d    %5.2f    %08s    %-8.4s

它的工作原理如下

  • 数字的整数部分指定输出将使用的最小 "宽度",或空格数,但如果输出太长而无法容纳,则输出可能会超过该宽度。
  • 数字的小数部分指定对于字符串,要打印的最大字符数;或者对于浮点格式,要打印的小数点右边的数字个数。
  • 前导 "-" 指定左对齐输出。默认情况下是右对齐输出。
  • 前导 "0" 指定输出用前导零填充,以填满输出字段。默认情况下是空格。

例如,考虑字符串的输出

   x = "Baryshnikov"
   printf("[%3s]\n",x)     # yields: [Baryshnikov]
   printf("[%16s]\n",x)    # yields: [     Baryshnikov]
   printf("[%-16s]\n",x)   # yields: [Baryshnikov     ]
   printf("[%.3s]\n",x)    # yields: [Bar]
   printf("[%16.3s]\n",x)  # yields: [             Bar]
   printf("[%-16.3s]\n",x) # yields: [Bar             ]
   printf("[%016s]\n",x)   # yields: [00000Baryshnikov]
   printf("[%-016s]\n",x)  # yields: [Baryshnikov     ]

—或整数

   x = 312
   printf("[%2d]\n",x)   # yields: [312]
   printf("[%8d]\n",x)   # yields: [     312]
   printf("[%-8d]\n",x)  # yields: [312     ]
   printf("[%.1d]\n",x)  # yields: [312]
   printf("[%08d]\n",x)  # yields: [00000312]
   printf("[%-08d]\n",x) # yields: [312     ]

—或浮点数

   x = 251.67309
   printf("[%2f]\n",x)     # yields: [251.67309]
   printf("[%16f]\n",x)    # yields: [      251.67309]
   printf("[%-16f]\n",x)   # yields: [251.67309      ]
   printf("[%.3f]\n",x)    # yields: [251.673]
   printf("[%16.3f]\n",x)  # yields: [        251.673]
   printf("[%016.3f]\n",x) # yields: [00000000251.673]
华夏公益教科书