Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Linux Awk 命令進階實戰:數據分析、報表生成與腳本化編程全解析

編輯:Linux 教學

Awk (Aho, Weinberger, Kernighan) 是一門圍繞「模式-動作」範式設計的數據驅動腳本語言,擅長列式數據切分、聚合統計、報表格式化、關聯數組建模,是日志分析、CSV/TSV 處理、系統巡檢報表的首選工具。

核心執行流程

  1. 讀取一行記錄(默認以換行符分隔,RS 可調)。
  2. 按字段分隔符 (FS/-F) 切分為 $1、$2...$NF,$0 為整行。
  3. 按腳本順序檢查每個模式,匹配則執行對應動作。
  4. 循環直到 EOF,執行 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/RLENGTHmatch() 函數匹配位置/長度動態

模式類型與動作語句

模式觸發條件示例
/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。

進階實戰範例

1. CSV/TSV 列統計與報表


# 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

2. 日志分析:Top 10 URL + 狀態碼分布


# 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]

3. 多文件合併去重 (以第一字段為鍵)


awk '!seen[$1]++' file1.txt file2.txt file3.txt > merged_unique.txt

4. 關聯數組模擬多維表 (二維統計)


# 統計每小時每狀態碼請求數
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

5. 格式化輸出對齊 (printf)


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

Gawk 專有擴展 (GNU Awk 4+)

  • 真正多維數組:arr[i][j] 語法糖。
  • 網絡 I/O:/inet/tcp/0/host/port、/inet/udp/... 直接 Socket 通信。
  • 時間函數:strftime()、systime()、mktime()。
  • 正則捕獲組:match($0, /(GET|POST) (.+) HTTP/, arr) → arr[1], arr[2]。
  • 排序函數:asort()、asorti()。
  • JSON 輸出:@include "json" 扩展库。

最佳實踐建議

  • 大文件 (>1G) 考慮 mawk (極快) 或並行 awk + split。
  • 複雜邏輯拆分為 -f script.awk 文件,便於版本控制與復用。
  • 數值計算注意精度:Awk 內部用雙精度浮點,大整幂建議用 bc 或 Python。
  • 避免在動作中打開/關閉文件,使用 print > "file" 重定向或管道。
  • 調試技巧:awk '...' file | head -20、awk '...{print "DEBUG:",$0}' file。
Copyright © Windows教程網 All Rights Reserved