Awk (Aho, Weinberger, Kernighan) 是一門圍繞「模式-動作」範式設計的數據驅動腳本語言,擅長列式數據切分、聚合統計、報表格式化、關聯數組建模,是日志分析、CSV/TSV 處理、系統巡檢報表的首選工具。
RS 可調)。FS/-F) 切分為 $1、$2...$NF,$0 為整行。END 塊。
awk '程序' 文件...
awk -f 程序文件 文件...
awk -F ':' '程序' /etc/passwd # 指定字段分隔符
awk -v var=value '程序' # 傳遞外部變量
awk 'BEGIN{...} 模式{動作} ... END{...}' # 完整結構
| 變量 | 含義 | 默認/說明 |
|---|---|---|
FS | 輸入字段分隔符 | 空白字符 (空格/Tab) |
OFS | 輸出字段分隔符 | 空格 |
RS | 輸入記錄分隔符 | 換行符 |
ORS | 輸出記錄分隔符 | 換行符 |
NF | 當前記錄字段數 | 動態 |
NR | 已讀記錄總數 (跨文件累計) | 動態 |
FNR | 當前文件記錄號 | 每文件重置 |
FILENAME | 當前文件名 | 動態 |
ARGC/ARGV | 命令行參數計數/數組 | 可在 BEGIN 中修改 |
ENVIRON | 環境變量關聯數組 | ENVIRON["HOME"] |
RSTART/RLENGTH | match() 函數匹配位置/長度 | 動態 |
| 模式 | 觸發條件 | 示例 |
|---|---|---|
/regex/ | 記錄匹配正則 | /ERROR/{print $0} |
$3 ~ /pattern/ | 第 3 字段匹配 | $2 ~ /^192\.168\./ |
NR==1 | 第一行 (通常做表頭) | NR==1{print "HEADER"} |
NR>1 && $5>100 | 複合條件 | NR>1 && $5>100{sum+=$5} |
BEGIN | 讀取前初始化 | BEGIN{FS=","; OFS="|"} |
END | 讀取後匯總 | END{print "Total:", total} |
動作語句:{stmt; stmt; ...} 支援 C 風格語法:變量賦值、算術/字符串運算、if/else、for/while、break/continue、next/nextfile、exit、函數調用、print/printf、系統命令 system()、管道 cmd | getline。
# sales.csv: Date,Product,Qty,Price
awk -F, '
BEGIN { OFS="\t"; print "Product", "Total_Qty", "Total_Amount", "Avg_Price" }
NR>1 { qty[$2]+=$3; amt[$2]+=$3*$4; cnt[$2]++ }
END {
for (p in qty) {
avg = amt[p] / qty[p]
printf "%s\t%d\t%.2f\t%.2f\n", p, qty[p], amt[p], avg
}
}' sales.csv
# nginx access.log: $1=IP $7=URL $9=Status
awk '
{ url[$7]++; status[$9]++; total++ }
END {
print "=== Top 10 URLs ==="
n=0
for (u in url) { urls[++n]=u; cnt[n]=url[u] }
# 簡單冒泡排序 (小數據量)
for (i=1;i<=n;i++) for (j=i+1;j<=n;j++) if (cnt[i]
awk '!seen[$1]++' file1.txt file2.txt file3.txt > merged_unique.txt
# 統計每小時每狀態碼請求數
awk '
{ hour[strftime("%H",$1)]++; code_hour[$9","strftime("%H",$1)]++ }
END {
for (h in hour) {
for (c in code_hour) { split(c,a,","); if (a[2]==h) printf "Hour %s | Status %s | Count %d\n", h, a[1], code_hour[c] }
}
}' access.log
awk -F: 'BEGIN{printf "%-20s %5s %5s %s\n","User","UID","GID","Shell"} {printf "%-20s %5d %5d %s\n",$1,$3,$4,$7}' /etc/passwd
arr[i][j] 語法糖。/inet/tcp/0/host/port、/inet/udp/... 直接 Socket 通信。strftime()、systime()、mktime()。match($0, /(GET|POST) (.+) HTTP/, arr) → arr[1], arr[2]。asort()、asorti()。@include "json" 扩展库。mawk (極快) 或並行 awk + split。-f script.awk 文件,便於版本控制與復用。bc 或 Python。print > "file" 重定向或管道。awk '...' file | head -20、awk '...{print "DEBUG:",$0}' file。