[Linux] 整理/統計 Log – awk
[Linux] 整理/統計 Log – awk

[Linux] 整理/統計 Log – awk

[Linux] AWK 筆記

前言

我們常常需要利用Log去找過去到底發生甚麼事(?)
有時候牽涉到數量想計算處理的時候,awk就可以很方便地幫我們處理
當然還是可以把紀錄會出來用excel去做處理
主要是多了一個方法,當我們無法匯出檔案或是檔案太大(匯到自己電腦開起來可能會熱到可以煎蛋)


主要概念

  • awk可用column的概念去理解
Column 1 Column 2 Column 3
Text 1-1 Text 1-2 Text 1-3
Text 2-2 Text 2-2 Text 2-3
  • 上面的Column或是Text就是我們要抓的資料
    • Column 1 => $1
    • Column 2 => $2
    • Column 3 => $3
    • NR == '2'=> Text 2-2 Text 2-2 Text 2-3
  • 每欄之間的線就是我們所謂的分割方式
    • awk -F '|'
  • 來源本身有沒有切分
    • 沒有的話要用什麼切分
  • 切割字串
    • 分段方式
      awk -F [分段的依據]
  • 擷取行數
  • 資料處理
  • 單純撈資料可以用grep即可

各種Print系列

  • File
    Key Value
    1   line1
    2   line2
    3   line3
    4   line4
    5   line5
    6   line6
    7   line7
    8   line8
    9   line9
    10  line10
  • 完整的印出整個File
    awk '{print $0}' [file]
    awk 'NR % n == 0' [file]
    Key Value
    1   line1
    2   line2
    3   line3
    4   line4
    5   line5
    6   line6
    7   line7
    8   line8
    9   line9
    10  line10
  • 每三行印一次
    awk 'NR % 3 == 0' [file]
    2   line2
    5   line5
    8   line8
  • 印出特定column
    awk '{print $1,$3}' [file]
    Key
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
  • 只印出第一個column
    awk '{print $1}' [file]
    Key
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
  • 接續上面的,印出已經讀出的資料
  • 讀出來去掉第一行
    NR 已讀出行數,行號從一開始
    awk 'NR!=1{print $1}' [file]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
  • 用正則表達式印出特定行數
    # 第一個column含有Deepak
    awk '$0 ~ /Deepak/{print}' [file]
    awk '$0 ~ /10/{print}' [file]
    10  line10
    awk '$1 !~ /Deepak/{print}' [file]
    awk '$1 !~ /line/{print}' [file]
    Key Value
  • 指定列數等於某個字串
    awk '{ if($列數 == "字串") print $0 }' [file]
    awk '{ if(0 == "7") print $0 }' [file]
    7

    腳本

  • 架構

    BEGIN{
    執行前要執行的
    }
    {
    中間執行的
    }
    END{
    處理完要執行的
    }
    $ cat cal.awk
    #!/bin/awk -f
    #运行前
    BEGIN {
    math = 0
    english = 0
    computer = 0
    
    printf "NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL\n"
    printf "---------------------------------------------\n"
    }
    #运行中
    {
    math+=$3
    english+=$4
    computer+=$5
    printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5
    }
    #运行后
    END {
    printf "---------------------------------------------\n"
    printf "  TOTAL:%10d %8d %8d \n", math, english, computer
    printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR
    }
$ awk -f cal.awk score.txt
NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL
---------------------------------------------
Marry  2143     78       84       77      239
Jack   2321     66       78       45      189
Tom    2122     48       77       71      196
Mike   2537     87       97       95      279
Bob    2415     40       57       62      159
---------------------------------------------
  TOTAL:       319      393      350
AVERAGE:     63.80    78.60    70.00

JOIN 系列

  • 把資料合併起來

  • 合併並加上其他符號

  • file

    START
    Unix
    Linux
    START
    Solaris
    Aix
    SCO
  • Join Start以後的列

    awk '/START/{if (NR!=1)print "";next}{printf $0}END{print "";}' [file]
    UnixLinux
    SolarisAixSCO
  • Join Start以後的列,並以逗號分開

    awk '/START/{if (x)print x;x="";next}{x=(!x)?$0:x","$0;}END{print x;}' [file]
    Unix,Linux
    Solaris,Aix,SCO

    計算

    加總

  • file

    Item1,200
    Item2,500
    Item3,900
    Item2,800
    Item1,600
  • 第二行加總

    awk -F"," '{x+=$2}END{print x}' [file]
  • set

    awk -F, '{a[$1];}END{for (i in a)print i;}' [file]
    Item1
    Item2
    Item3
  • 連接數值
    OFS 斷行

    awk -F, '{a[$1]=a[$1]?a[$1]":"$2:$2;}END{for (i in a)print i, a[i];}' OFS=, [file]
    Item1,200:600
    Item2,500:800
    Item3,900

    使用案例

  • grep 檔案以後使用awk處理,處理後將資料寫到一個檔案

    zgrep -hi 'xxxxxx' [file] | awk -F ' ' '{print $10}' | grep -v 'Cnt=0' | awk -F '"' '{print $1}' > [寫到某個檔案]
    參考文件
  • awk應用參考

  • 文件

    tags: linux awk