Linux awk 資料處理與分析神器
awk(名稱來自三位開發者 Aho, Weinberger, Kernighan)是 Linux 上最強大的文字分析工具。
它把檔案視為一張「試算表」,一行是一筆記錄 (Record),一欄是一個欄位 (Field)。
最常用來做:擷取特定欄位(例如只看 Log 的 IP 欄位)。
基本語法
awk '{print $欄位編號}' 檔案
$0:代表「整行」$1:代表「第 1 欄」$2:代表「第 2 欄」$NF:代表「最後一欄」 (Number of Fields)
預設使用 空白 或 Tab 作為分隔符號。
常用範例
1. 顯示檔案的第一欄
# 列出系統所有使用者帳號 (格式是 root:x:0:0...)
# 這裡用 -F 指定用冒號 : 分隔
awk -F ':' '{print $1}' /etc/passwd
2. 也是 grep:條件過濾
awk 也可以用來搜尋。
# 只顯示 UID 大於 1000 的使用者
awk -F ':' '$3 >= 1000 {print $1, $3}' /etc/passwd
# 搜尋包含 "error" 的行 (類似 grep error)
awk '/error/ {print $0}' /var/log/syslog
3. 統計與計算
假設有一個薪資檔 salary.txt (姓名 薪水):
Alice 3000
Bob 4500
Charlie 2800
我們可以輕鬆算總和:
awk '{sum += $2} END {print "Total:", sum}' salary.txt
內建變數
NR(Number of Records):目前處理到第幾行。FS(Field Separator):分隔符號 (預設空白)。OFS(Output Field Separator):輸出的分隔符號 (預設空白)。
加上行號顯示
awk '{print NR, $0}' /etc/passwd
## 進階格式化輸出 (`printf`)
`print` 會自動換行,但如果有時候你想印出漂亮的表格,就要用 `printf` (跟 C 語言很像)。
```bash
# %-10s: 字串靠左佔 10 格
# %5d: 整數靠右佔 5 格
awk -F ':' '{printf "User: %-15s UID: %5d\n", $1, $3}' /etc/passwd
BEGIN 與 END 區塊
這是 awk 的程式架構:
- BEGIN: 讀取檔案前執行一次 (通常用來初始化變數或印標題)。
- Main: 每一行都會執行一次。
- END: 讀完所有檔案後執行一次 (通常用來印總結)。
awk 'BEGIN {print "Name\tSalary"}
{print $1, "\t", $2}
END {print "--------------\nDone"}' salary.txt
邏輯控制 (If-Else)
awk 其實是一門完整的程式語言,支援 if, for, while。
# 如果 UID >= 1000 印 "User",否則印 "System"
awk -F ':' '{
if ($3 >= 1000)
print $1, "is User"
else
print $1, "is System"
}' /etc/passwd
內建字串函數
length($0): 計算長度toupper($1)/tolower($1): 轉大小寫substr($1, 1, 3): 取子字串
# 印出長度超過 20 的行
awk 'length($0) > 20' /var/log/syslog
實戰:Nginx Log 分析
假設 Log 格式如下:
192.168.1.1 - - [12/Dec/2023...] "GET /index.html..." 200 1024
統計每個 IP 的存取次數 (最重要的指令!)
這招必學!用 Array 來計數。
# $1 是 IP
awk '{count[$1]++} END {for (ip in count) print count[ip], ip}' access.log | sort -nr | head
count[$1]++: 建立一個叫做count的陣列,Key 是 IP ($1),每次遇到就 +1。END { ... }: 讀完後跑迴圈,印出結果。sort -nr: 照數字大小反向排序 (最多的在上面)。