跳轉到內容

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