007 Linux 命令三劍客之-awk

不甩鍋的碼農 發表於 2022-01-26
Linux

01 一起來認識 awk!

Linux 命令三劍客,sed、grep、awk。

  • sed:擅長資料修改。
  • grep:擅長資料查詢定位。
  • awk:擅長資料切片,資料格式化,功能最複雜。

awk 更適合格式化文字,對文字進行較複雜格式處理,awk 程式對輸入檔案的每一行進行操作。awk 是一門解釋型的程式語言。文字處理、輸出格式化的文字報表、執行算數運算、執行字串操作等等。

02 awk 完整命令格式

BEGIN { …. initialization awk commands …}{ …. awk commands for each line of the file…}END { …. finalization awk commands …}
  • BEGIN{} 語句塊在程式的開頭執行,它只執行一次,在這裡可以初始化變數。BEGIN 是 awk 的關鍵字,因此它必須為大寫,注意,這個語句塊是可選的;
  • 主{ }部分,沒有關鍵字,執行處理檔案的每一行執行的命令;
  • END 語句塊在程式的最後執行,END 是 awk 的關鍵字,因此必須為大寫,它也是可選的。

03 awk 間隔符(分隔符)

  • awk 將每一行視為由多個欄位組成,每個欄位由"間隔符"分隔。預設情況下"間隔符" 是一個或多個空格字元,因此行:this is a line of text 包含6個欄位。在 awk 中,第一個欄位稱為 $1,第二個欄位稱為 $2,以此類推,整行稱為 $0。
  • awk 內建變數 FS 可以設定間隔符,如設定 FS=":",則它將根據':'作為間隔符。

04 awk 內建變數及可選引數

【內建變數】

  • FS # 輸入欄位的分隔符
  • NR # 當前行號,已讀的記錄數
  • NF # 當前行中的欄位數量
  • $NF # NF 當前行中的欄位數量(行引數數量),假如行引數有六個,那麼NF=6,重點來了,如果我要取當前行的最後一個引數,使用 "$6" 和 "$NF" 都能取到最後一個引數,也就是說 $6=$NF=第6個引數值。

【常用可選引數】

  • -v # 賦值一個使用者定義變數
  • -f # 從指令碼檔案中讀取 awk 命令
  • -F # 相當於內建變數 FS

05 awk 模式匹配

  • awk 可以對任何檔案進行操作,包括 std-in,在這種情況下,它通常與 '|' 命令一起使用,例如,結合 grep,cat 或其他命令。
  • awk 是一種面向行的語言。首先是模式,然後是動作。操作語句用" {} "括起來。
  • awk 模式包括正規表示式 (使用與“grep -E”相同的語法) 和使用的組合特殊符號 “&&” 表示“邏輯AND ”,“||”表示“邏輯或”,“!” 的意思是“邏輯不”。

06 awk 控制語句

awk 'BEGIN{ commands } pattern{ commands } END{ commands }'

eg:統計指定ip和埠號,各種 tcp 連線狀態的數量

netstat -n | grep 1.2.3.4:22 | awk '/^tcp/ {++State[$NF]} END {for (i in State) print i, State[i]}'
  • 命令中,^tcp用於匹配開頭包含tcp字元的文字行;
  • $NF 指的是每行最後一個欄位,陣列State[$NF]就是以最後一個欄位為下標指向一個儲存單元或者說變數,此處代表該欄位的統計結果, 也就是++的意義所在, 統計值自增一。
  • END不能缺少表示END符號之後的指令於處理所有行結束時執行。
  • i是欄位,State[i]即為統計結果,每行處理完成則State[$NF] 加1。

07 awk 常用實踐

  • 統計文字行數
awk 'END  {print NR}' warn.log #統計 warn.log 檔案行數。
  • 指定以 , 為分隔符;輸出為 hello world。
    文字內容如下:
    hello,world,awk,!
awk -F, '{print $1,$2}' info.log # -F, 指定以逗號分隔。
  • 實現計算表示式
awk 'BEGIN{print  115+100}'

08 小結

awk 命令,擅長文字格式化處理,這裡只是起到一個拋磚引玉的作用,awk 語法較為複雜,感興趣的可以深入學習,當然你也可以用 python 等語言來做一些指令碼任務的處理。

「不甩鍋的碼農」原創,轉載請註明來源,未經授權禁止商業用途!同名 GZH 請關注!