AWK 是什麼?
AWK 以三位創始人(Alfred Aho、Peter Weinberger、Brian Kernighan)姓氏首字母命名,是一門功能強大的模式掃描與處理語言。它不僅是 Linux 文本處理利器,更擁有完整編程語言特性:變量、數組、函數、流控制、數學運算、正則表達式、進程控制等。
為什麼選擇 AWK?
- 文本數據庫特性:處理無固定格式的文本文件,比數據庫更輕量、更通用。
- 開發效率高:一行命令解決簡單問題,複雜邏輯寫腳本,無需編譯,解釋執行,與 Shell 無縫集成。
- 學習曲線平緩:語法吸收 C 語言精華,但去除指針、手動內存管理等複雜特性。
- 普遍可用:幾乎所有 Unix/Linux 系統預裝
/bin/awk(或 gawk GNU 版)。
核心語法
awk '{pattern + action}' {filenames}
pattern:匹配條件(正則、關係表達式、範圍模式等),可省略(默認匹配所有行)。
action:匹配時執行的命令序列(花括號包裹),可省略(默認打印整行 {print})。
調用方式
- 命令行模式:
awk '/pattern/ {action}' file,適合臨時任務。
- 腳本文件模式:
awk -f script.awk file,適合複雜邏輯,支持 #!/usr/bin/awk -f 羊角號直接執行。
- 管道/重定向:
cmd | awk '...'、awk '...' file > out。
內置變量速查
| 變量 | 含義 |
| $0 | 整行內容 |
| $1-$n | 第 1~n 個字段(默認空白分隔) |
| NF | 當前行字段數 |
| NR | 已讀記錄數(跨文件累計) |
| FNR | 當前文件記錄數 |
| FS | 輸入字段分隔符(默認空白,可用 -F 指定) |
| OFS | 輸出字段分隔符(默認空格) |
| RS | 輸入記錄分隔符(默認換行) |
| ORS | 輸出記錄分隔符(默認換行) |
| FILENAME | 當前輸入文件名 |
經典實戰範例
1. 提取特定列並格式化輸出
awk -F: '{printf "%-15s %s\n", $1, $3}' /etc/passwd
以冒號分隔,打印用戶名($1)和 UID($3),左對齊 15 字符。
2. 統計文件行數、字數、字符數
awk '{lines++; words+=NF; chars+=length($0)+1} END {print lines, words, chars}' file
3. 範圍模式:打印第 10-20 行
awk 'NR>=10 && NR<=20' file
4. 多文件處理:合併同名文件
awk 'FNR==1 {print "=== " FILENAME " ==="} {print}' *.log
5. 關聯數組去重統計
awk '{count[$1]++} END {for (ip in count) print ip, count[ip]}' access.log
進階特性
- 用戶自定義函數:
function name(args) { ... }
- 系統交互:
system(cmd)、getline 讀取外部命令輸出。
- 正則增強:
~/!~ 匹配操作符、gensub()、sub()、gsub() 替換函數。
- 雙向管道(gawk):
command |& getline。
AWK vs sed vs grep
| 工具 | 定位 | 優勢場景 |
| grep | 模式搜索 | 單純過濾匹配行,速度最快 |
| sed | 流編輯器 | 行級編輯、替換、刪除、插入 |
| awk | 數據處理語言 | 列提取、計算、報表生成、複雜邏輯 |
原則:grep 過濾 → sed 編輯 → awk 分析計算,三者管道組合威力無窮。