awk 不僅是文本處理工具,更是一門圖靈完備的腳本語言。作為「文本處理三劍客」中功能最強大的一環,awk 擅長列式數據提取、格式化報表生成、複雜邏輯運算。本文系統梳理調用方式、內置變量、輸出函數、外部變量傳遞四大核心知識體系,配合實戰場景案例,助您從入門進階至專家級應用。

awk [-F '分隔符'] '程序碼' 文件1 文件2 ...
# 示例:以冒號分隔 /etc/passwd,打印用戶名與 Shell
awk -F: '{print $1, $NF}' /etc/passwd
要點:單引號包裹程序碼防止 Shell 變量展開;-F 支援正則表達式 (如 -F'[:,]')。
#!/usr/bin/awk -f
# 腳本體
BEGIN { FS=":"; OFS="\t" }
{ print $1, $3, $7 }
END { print "Total users:", NR }
chmod +x script.awk
./script.awk /etc/passwd
awk -f script.awk input.txt
| 變量 | 含義 | 默認值/示例 |
|---|---|---|
FS | 輸入字段分隔符 | 空白字符 (空格/Tab) |
OFS | 輸出字段分隔符 | 空格 |
RS | 輸入記錄分隔符 | 換行符 \n |
ORS | 輸出記錄分隔符 | 換行符 \n |
NR | 已讀記錄總數 (跨文件累計) | 行號,從 1 開始 |
FNR | 當前文件記錄數 | 多文件時每文件歸零 |
NF | 當前記錄字段數 | $NF 為最後一字段 |
FILENAME | 當前處理文件名 | - |
$0 | 完整當前記錄 | 整行內容 |
$1-$n | 第 n 個字段 | 由 FS 分隔 |
ARGC/ARGV | 命令行參數個數/數組 | ARGV[0] 為 awk 命令本身 |
ENVIRON | 環境變量關聯數組 | ENVIRON["PATH"] |
print $1, $3 # 逗號分隔 → 輸出用 OFS 連接
print $1 $3 # 無逗號 → 直接拼接
print "User:", $1 # 字符串常量需雙引號
printf "%-20s %5d %s\n", $1, $2, $3
# 格式符速查:
# %s 字符串 %d 十進制整數 %f 浮點數 %x 十六進制 %o 八進制
# %c 單字符 %e 科學計數法 %g 自適應
# 修飾:- 左對齊 數字寬度 .精度 0補零
awk -v threshold=100 '{if ($3 > threshold) print}' data.txt
# 或
awk 'BEGIN{th=100} $3>th' data.txt
export MY_VAR="hello"
awk 'BEGIN{print ENVIRON["MY_VAR"]}'
echo "param1 param2" | awk '{print $1, $2}'
awk '/ERROR/ {err[$5]++} END {for (e in err) print err[e], e}' app.log | sort -rn | head -10
awk -F, 'NR>1 {rev[$1]+=$4; qty[$1]+=$3} END {for (p in rev) printf "%s: Revenue=%.2f Qty=%d\n", p, rev[p], qty[p]}' sales.csv
awk 'NR==FNR {seen[$0]=1; next} !($0 in seen)' file1 file2
# 邏輯:先讀 file1 存入 seen,再處理 file2 只輸出未見過的行
$1+0 > $2+0 或 ($1 > $2) + 0$1 ~ /^root$/ 整字段匹配,$1 ~ /root/ 子串匹配sort | uniq -c 流式處理FS/OFS 修改時機:BEGIN 塊修改影響全局,主塊修改僅影響後續記錄awk 的核心價值在於 模式-動作 範式與豐富內置變量的組合爆發力。掌握 FS/OFS/RS/ORS 四大分隔符控制、NR/FNR/NF 三大計數器語義、print/printf 雙輸出模式、-v/ENVIRON 變量注入,即可應對 95% 文本處理需求。進階之路建議深入學習:多維數組模擬關係運算、getline 主動讀取控制、協同 sort/join 完成類 SQL 查詢。工具無強弱,唯場景與熟練度論英雄。