1. 程式人生 > 其它 >三劍客之 awk用法

三劍客之 awk用法

awk

  AWK 是一種處理文字檔案的語言,是一個強大的文字分析工具。
  之所以叫 AWK 是因為其取了三位創始人 Alfred Aho,Peter Weinberger 和 Brian Kernighan 的 Family Name 的首字元。
  相較於sed常常作用於一整個行的處理,awk則比較傾向於一行當中分成數個欄位來處理,因為awk相當適合小型的文字資料。

 基本格式

1 awk [選項引數] 'script' var=value file(s)
2 3 awk [選項引數] -f scriptfile var=value file(s)

awk後面接兩個單引號並加上大括號{ }

來設定想要對資料進行的處理操作,awk可以處理後續接的檔案,也可以讀取來自前個命令的標準輸,但如果awk主要是處理每一行的欄位內的資料時,預設的欄位分隔符為“空格鍵”或“Tab鍵”

 工作原理

  • 逐行讀取文字預設以空格或tab鍵為分隔符進行分隔,將分隔所得的各個欄位儲存到內建變數中, 並按模式或者條件執行編輯命令
  • sed命令常用於一整行的處理,而awk比較傾向於將一行分成多個"欄位"然後再進行處理。awk資訊的讀入也是逐行讀取的,執行結果可以通過print的功能將欄位資料列印顯示。在使用awk命令的過程中,可以使用邏輯操作符"&&“表示"與”"| |"表示"或”"!“表示"非";
    還可以進行簡單的數學運算,如+、-、*、/、%、^分別表示加、減、乘、除、取餘和乘方

 常見的內建變數(可直接用)

FS∶ 列分割符。指定每行文字的欄位分隔符,預設為空格或製表位。與"-F"作用相同
NF∶ 當前處理的行的欄位個數
NR∶ 當前處理的行的行號(序數)
$0∶當前處理的行的整行內容
$n∶ 當前處理行的第n個欄位(第n列)
FILENAME∶ 被處理的檔名。
RS∶ 行分隔符。awk從檔案上讀取資料時,將根據RS的定義把資料切割成許多條記錄,而awk一次僅讀入一條記錄,以進行處理。預設值是’\n’

按行輸出文字

例項1:輸出全部內容

例項2:輸出第1到第3行的內容

例項3:輸出第1行和第3行的內容,輸出奇數和偶數行

例項4:輸出包含指定字元的行

例項5:輸出包含指定字元的行並統計有多行

  BEGIN模式表示,在處理指定的文字之前,需要先執行BEGIN模式中指定的動作;   awk再處理指定的文字,之後再執行END模式中指定的動作;   END{ } 語句塊中,往往會放入列印結果等語句

按欄位輸出文字

例項1:輸出指定分隔符的指定欄位

例項2:輸出指定欄位在指定範圍內的行,並選擇輸出的欄位

例項3:awk結合三元運算子的使用

通過管道、雙引號呼叫shell命令

 1 echo $PATH | awk 'BEGIN{RS=":"};END{print NR}'                                    #統計以冒號分隔的文字段落數,END{}語句塊中,往往會放入列印結果等語句
 2 
 3 awk -F: '/bash$/{print | "wC -1"}' /etc/passwd                                    #呼叫wc -1命令統計使用bash 的使用者個數,等同於grep -c "bash$" /etc/passwd
 4 
 5 free -m | awk '/Mem:/ {print int($3/($3+$4)*100)"%"}'                             #檢視當前 記憶體使用百分比
 6 
 7 top -b -n 1| grep Cpu | awk-F ',' '{print$4}'| awk '{print$1}'                    #檢視當前CPU空閒率,(-b-n 1 表示只需要1次的輸出結果)
 8 
 9 date -d "$ (awk -F "." '{print $1}' /proc/uptime) second ago" +"%F %H: %M: %S"    #顯示上次系統重啟時間,等同於upt ime; second ago為顯示多少秒前的時間,+"%F %H: %M:%S"等同於+"*Y-%m-%d %H:%M:%S"的時間格式
10 
11 awk 'BEGIN {n=0 ; while ("w" | getline) n++ ; {print n-2}}'                       #呼叫w命令,並用來統計線上使用者數
12 
13 awk 'BEGIN {"hostname" | getline ; {print $0}}'                                   #呼叫hostname, 並輸出當前的主機名
1 CPU使用率
2 
3 cpu_us=`top -b -n 1 | grep Cpu | awk '{print $2}'`
4 cpu_sy=`top -b -n 1 | grep Cpu | awk -F ',' '{print $2}' | awk '{print $1}'`
5 cpu_sum=$(($cpu_us+$cpu_sy))
6 echo $cpu_sum

當getline左右無重定向符“<”或“1”時,awk首先讀取到了第一行,就是1,然後getline, 就得到了1下面的第二行,就是2,因為getline之後,awk會改變對應的NF, NR, FNR和$0等內部變數,所以此時的$0的值就不再是1,而是2了,然後將它打印出來

當getline左右有重定向符“<”或“|”時,getline則作用於定向輸入檔案,由於該檔案是剛開啟,並沒有被awk讀入一行,只是getline讀入,那麼getline返回的是該檔案的第一 行,而不是隔行

1 seq 10 | awk '{getline; print $0}'
2 seq 10 | awk '{print $0; getline}'

注:seq 用於生成從一個數到另一個數之間的所有整數

1 echo "A B C D" | awk '{OFS="|";print $0;$1=$1;print $0}'
2 ABCD
3 AIBICID
4 $1=$1是用來啟用$0的重新賦值,也就是說欄位$1...和欄位數NF的改變會促使awk重新計算$0的值,通常是在改變OFS後而需要輸出$0時這樣做

使用awk統計httpd訪問日誌中每個客戶端IP的出現次數

1 awk '{ip[$1]++}END{for(i in ip) {print ip[i],i}}' /var/log/httpd/access_log | sort -r
2 
3 備註:定義陣列,陣列名稱為ip,數字的下標為日誌檔案的第1列(也就是客戶端的IP地址),++的目的在於對客戶端進行統計計數,客戶端.
4 IP出現一次計數器就加1。END中的指令在讀取完檔案後執行,通過迴圈將所有統計資訊輸出,for 迴圈遍歷的是陣列名ip的下標

cpu負載,記憶體容量,硬碟空間,網絡卡流量,安裝的軟體包數量,賬戶數量,當前登入的賬戶數量,程序數量,輸錯密碼的主機

1 uptime, free -m,df -h, ifconfig ens33, rpm -qa|wc -l, /etc/passwd, who,ps aux, /var/log/secure

過濾密碼失敗的命令

1 awk 'BEGIN {ip[$11]=0}; /Failed password/ {ip[$11]++};END {for(i in ip){print i,ip[i]}}' /var/log/secure

cpu 使用情況

1 #!/bin/bash
2 
3 us=`top -b -n 1 | grep Cpu | awk '{print $2}'`
4 echo "使用者佔用率為:" $us
5 sy=`top -b -n 1 | grep Cpu | awk -F "," '{print $2}' | awk '{print $1}'`
6 echo "核心佔用率為:" $sy
7 id=`top -b -n 1 | grep Cpu | awk -F ',' '{print $4}'| awk '{print $1}'`
8 echo "cpu空閒率為:" $id