跳轉到內容

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]
華夏公益教科書