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 請關注!