跳轉到內容

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,計算每行的平均單詞數。
華夏公益教科書