Linux 伺服器系統管理第十二章 Sed 與 awk 處理工具  上一頁    下一頁

12-2 Awk 資料處理語言

內容:

12-2-1 Awk 簡介

Awk 的名字是取自 AhoWeinbergerKernighan 等三位設計者的字首,它是 Unix 系統裡非常重要的工具之一;awk 也是由檔案內容上搜尋所欲編輯的內容,因此可稱為『圖樣掃描與處理語言』(Pattern scanning and processing language。一般 Linux 系統也都有類似 awk 的工具,大多取名為 gawk。雖然不同版本 Unix awk(或 gawk)或有些微不同,但大致上功能與語法還能夠相容,亦即利用 awk 編寫出來的系統工具,其可攜性都非常高。

命令 awk 是介於 Shell Script 與單獨命令之間的功能,它也有獨立的語法可供編寫程式,可以利用程式編輯的方法來設計命令的功能,除了如同 greptr、或 sed 一樣可以搜尋與編輯檔案內容,也可以像處理資料庫系統一樣,針對某些欄位的處理。一般情況下,編輯沒有規則的文件,還是利用 sed 工具較為恰當,至於格式化的檔案文件,利用 awk 就方便許多。再說,一般系統工具的輸出結果,大多有其一定規則的格式化文件,其中每一個欄位多半具有其特殊意思,處理這種文件當以 awk 最為恰當。譬如,執行 ls –l 命令的輸出結果,每一行表示一個檔案或目錄的屬性,其中第一個欄位表示存取權限、第二欄位為連結數量……等等(如下所示),如此具有資料庫型態的格式化,就可利用 awk 來萃取所需的資訊。

tsnien@Linux-1 tools]$ ls -l

總計 16

-rw-rw-r--  1 tsnien tsnien  36  2 27 10:04 file_1

-rw-rw-r--  1 tsnien tsnien 261  2 24 15:09 RedHat

-rw-rw-r--  1 tsnien tsnien 141  2 27 14:08 salary

12-2-2 Awk 命令格式

Awk 命令格式與 sed 非常相同,但它有兩種使用方法,一者為直接在命令上輸入處理動作(與sed同);另一者可將許多處理程式整合在一個命令稿上,再引入命令稿執行,其命令格式如下:

awk [option] ‘statement {action}’ input_file

awk –f program_file input_file

常用選項有:

Ø  -F fs:指定欄位之間的分隔器,如 ‘–F ,’,表示欄位之間是以『逗號』(,)分隔。

其他重點說明如下:

²  awk 的命令參數用兩個單引號包起來。

²  處理時導 input_file,結果顯示在標準輸出。

²  命令敘述(statement可以是單一命令,也可以由多命令組合而成,甚至編寫成檔案。命令敘述多半以搜尋條件為主。

²  statement 可利用正規式表示,大部分 sed vi 的命令都可以使用(不再重複介紹)。

²  當前面敘述的條件成功時,則執行 action 內的命令。

12-2-3 Awk 欄位操作

我們可以發現,處理 Unix 資料檔案都有其一定的格式,如同資料庫的記錄(record)一般。Awk 的處理動作就是一筆一筆記錄讀入,再比較判斷命令是否給予處理;同樣的,輸出也是一筆一筆記錄處理後,再送到標準輸出地方。如此一來,針對檔案內每一筆記錄欄位的表示,就顯得格外重要。文件中欄位位元表示方式如下:(如圖 12-2 範例)

²  $0 :為整筆記錄的所有資料。

²  $1 ~ $n:為第一個欄位到第 n 個欄位。

²  NFNumber of Fields:總共有幾個欄位(NF = 4)。

²  NRNumber of Records:總共有幾筆資料(NR = 4)。

 

12-2 文件欄位表示方式

以圖 12-2 為例,每一行表示一筆資料(或稱『記錄』),每一筆資料由 4 個欄位表示(許多 Unix/Linux 工具的輸出結果都類似此種型態)。值得注意的是,表示欄位之間的分隔符號號,如果沒有特殊指定的話,多半以一個或多個『空白格』、或『tab 鍵空格』(\t)表示。接下來,我們用一些簡單範例來說明 awk 欄位的操作方式,相信如此應能讓讀者儘快進入狀況。

A. awk 欄位範例一】

接下來幾個範例,我們利用 salary 檔案介紹 awk 操作,salary 是某一公司的員工檔案,每一行記錄一位員工的資料,其中包含員工姓名、年齡、底薪、以及電話號碼。我們利用 cat 命令觀察 salary 檔案,接著再利用 awk 讀出每一筆記錄並將它顯示於螢幕上,操作如下:

[tsnien@Linux-1 tools]$ cat salary

Frank   30      40000   07-3219092

George  48      50000   07-4553211

Nacy    51      70000   06-2851178

Louis   42      65000   04-3298101

[tsnien@Linux-1 tools]$ awk '{print $0}' salary

Frank   30      40000   07-3219092

George  48      50000   07-4553211

Nacy    51      70000   06-2851178

Louis   42      65000   04-3298101

上述 awk 命令 ‘{print $0}’ 中並沒有搜尋條件,表示每一筆記錄都符合條件,並印出該筆記錄所有內容(print $0)。

B. awk 欄位範例二】

顯示 salary 檔案中第一個欄位(姓名)與第三個欄位(底薪),欄位之間以 tab 鍵(\t)分隔,操作如下:

[tsnien@Linux-1 tools]$ awk '{print $1, "\t", $3}' salary

Frank    40000

George   50000

Nacy     70000

Louis    65000

C. awk 欄位範例三】

印出 salary 檔案內,員工電話於高雄地區(07)的姓名及電號,操作如下:

[tsnien@Linux-1 tools]$ awk '/07-/ {print $1, "\t", $4}' salary

Frank    07-3219092

George   07-4553211

其中 /07-/ 為搜尋敘述(statement),找出具有 07- 字串的記錄(即是『行』),才經過後面動作(action)的處理。

D. awk 欄位範例四】

員工中,年齡如超過 45 歲者,底薪增加 5000 元,並印出處理後員工的薪資及姓名,其中欄位之間用分號(;)分隔,操作如下

[tsnien@Linux-1 tools]$ awk '$2 > 45 {print $1, ";", $3 + 5000}' salary

George ; 55000

Nacy ; 75000

 

 

翻轉工作室:粘添壽

 

Linux 伺服器系統管理 - CentOS:

 

 

 

翻轉電子書系列: