1. 程式人生 > 其它 >Linux 三劍客之awk命令

Linux 三劍客之awk命令

Linux 三劍客之awk命令

一、awk命令

  • awk命令是一種程式語言,用於在linux/unix下對文字和資料進行處理。
  • 而且它支援使用者自定義函式和動態正則表示式等先進功能,是linux/unix下的一個強大程式設計工具。

1、工作原理

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

2、命令格式

awk 選項 '模式或條件  {操作}'  檔案1 檔案2 ...
awk -f  指令碼檔案 檔案1 檔案2 ...

3、awk常見的內建變數

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

二、按行輸出文字

awk '
{print}' testfile2 # 輸出所有內容 awk '{print $0}' testfile2 # 輸出所有內容 awk 'NR==1,NR==3{print}' testfile2 # 輸出第1~3行內容 awk '(NR>=1)&& (NR<=3){print}' testfile2 # 輸出第1~3 行內容 awk 'NR==1||NR==3{print}' testfile2 # 輸出第1行、第3行內容 awk '(NR號2)==1{print}' testfile2 # 輸出所有奇數行的內容 awk '(NR號2)==0{print}
'testfile2 # 輸出所有偶數行的內容 awk '/^x/{print}' /etc/passwd # 輸出以x 開頭的行 awk '/x$/{print}' /etc/passwd # 輸出以x 結尾的行 awk 'BEGIN {x=0};/\/bin\/bash$/{x++};END{print x}'/etc/passwd # 統計以/bin/bash結尾的行數,等同於grep -c "/bin/bash$" /etc/passwd BEGIN模式表示,在處理指定的文字之前,需要先執行BEGIN模式中指定的動作; awk再處理指定的文字,之後再執行END模式中指定的動作,END{}語句塊中, 往往會放入列印結果等語句

1、輸出所有內容

awk '{print}' testfile2     # 輸出所有內容
awk '{print $0}' testfile2          #  輸出所有內容

2、輸出1~3行內容

awk 'NR==1,NR==3{print}' testfile2                # 輸出第1~3行內容
awk '(NR>=1)&& (NR<=3){print}' testfile2   # 輸出第1~3 行內容

3、輸出第1行、第三行內容

awk 'NR==1||NR==3{print}' testfile2  # 輸出第1行、第3行內容

4、輸出奇數行、偶數行的內容

awk '(NR號2)==1{print}' testfile2   # 輸出所有奇數行的內容
awk '(NR號2)==0{print}'testfile2             # 輸出所有偶數行的內容

5、輸出以x 開頭,y 結尾的內容

awk '/^x/{print}' /etc/passwd     # 輸出以x 開頭的行
awk '/y$/{print}' /etc/passwd          #  輸出以y 結尾的行

三、按欄位輸出文字

awk -F ":" '{print $3}' /etc/passwd      # 輸出每行中(以空格或製表位分隔)的第3個欄位

awk -F ":" '{print $1,$3}' /etc/passwd   # 輸出每行中的第1、3個欄位

awk -F ":" '$3<5{print $1,$3}' /etc/passwd # 輸出第3個欄位的值小於5的第1、3個欄位內容

awk -F ":" '!($3<200){print}' /etc/passwd  # 輸出第3個欄位的值不小於200的行

awk 'BEGIN {FS=":"}; {if($3>=1000){print}}' /etc/passwd # 先處理完BEGIN的內容, 再列印文本里面的內容

awk -F ":" '{max=($3>=$4)?$3:$4;{print max}' /etc/passwd  # ($3>$4)?$3:$4三元運算子,如果第3個欄位的值大於等於第4個欄位的值,則把第3個欄位的值賦給max,否則第4個欄位的值賦給max

awk -F ":" '{print NR,$0}' /etc/passwd   # 輸出每行內容和行號,每處理完一條記錄,NR值加1

awk -F ":" '$7~"/bash"{print $1}' /etc/passwd   # 輸出以冒號分隔且第7個欄位中包含/bash的行的第1個欄位

awk -F ":" '($1~"root")&&(NF==7){print $1, $2}' /etc/passwd # 輸出第1個欄位中包含root且有7個欄位的行的第1、2個欄位

awk -F ":” '($7!="/bin/bash")&&($7!="/sbin/nologin"){print}' /etc/passwd  # 輸出第7個欄位既不為/bin/bash,也不為/sbin/nologin的所有行

1、輸出每行中(以空格或製表位分隔)的第3個欄位

awk -F ":" '{print $3}' /etc/passwd    # 輸出每行中(以空格或製表位分隔)的第3個欄位

2、輸出每行中的第1、3個欄位

awk -F ":" '{print $x,$y}' /etc/passwd   #輸出每行中的第x、y個欄位

3、輸出第三個欄位的值小於5的第1,三個欄位

awk -F ":" '$3<5{print $1,$3}' /etc/passwd #輸出第3個欄位的值小於5的第1、3個欄位內容

4、輸出第三個欄位的值不小於200的行

awk -F ":" '!($3<200){print}' /etc/passwd  # 輸出第3個欄位的值不小於200的行

5、先處理BEGIN的內容,再輸出文字內容

awk 'BEGIN {FS=":"}; {if($3>=1000){print}}' /etc/passwd     # 先處理完BEGIN的內容, 再列印文本里面的內容

6、運用三運運算子執行內容

awk -F ":" '{max=($3>$4)?$3:$4;{print max}}' /etc/passwd   #  ($3>$4)?$3:$4三元運算子,如果第3個欄位的值大於等於第4個欄位的值,則把第3個欄位的值賦給max,否則第4個欄位的值賦給max

7、輸出內容和行號

awk -F ":" '{print NR,$0}' /etc/passwd   # 輸出每行內容和行號,每處理完一條記錄,NR值加1

8、輸出每行第七個欄位包含/bash的行的第一個欄位

awk -F ":" '$7~"/bash"{print $1}' /etc/passwd   #輸出以冒號分隔且第7個欄位中包含/bash的行的第1個欄位

9、輸出第一個欄位中包含root且有起個欄位的行的第1、2個字元

awk -F ":" '($1~"root")&&(NF==7){print $1, $2}' /etc/passwd #輸出第1個欄位中包含root且有7個欄位的行的第1、2個欄位

10、輸出第七個欄位既不是/bin/bash/也不是/sbin/nologin的所有行

awk -F ":" '($7!="/sbin/nologin")&&($7!="bin/bash"){print NR,$0}' /etc/passwd  # 輸出第7個欄位既不為/bin/bash,也不為/sbin/nologin的所有行

四.通過管道,雙引號呼叫shell命令

echo $PATH | awk 'BEGIN{RS=":"};END{print NR}'   # 統計以冒號分隔的文字段落數,END{}語句塊中,往往會放入列印結果等語句

awk -F: '/bash$/{print | "wC -1"}' /etc/passwd   # 呼叫wc -1命令統計使用bash 的使用者個數,等同於grep -c "bash$" /etc/passwd

free -m | awk '/Mem:/ {print int($3/($3+$4)*100)"%"}'  # 檢視當前 記憶體使用百分比

top -b -n 1| grep cpu | awk-F ',' '{print$4}'| awk '{print$1}'   # 檢視當前CPU空閒率,(-b-n 1 表示只需要1次的輸出結果)

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"的時間格式

awk 'BEGIN {n=0 ; while ("w" | getline) n++ ; {print n-2}}' # 呼叫w命令,並用來統計線上使用者數

awk 'BEGIN {"hostname" | getline ; {print $0}}'  # 呼叫hostname, 並輸出當前的主機名

1、統計以冒號分割的文字段落數

echo $PATH | awk 'BEGIN{RS=":"};END{print NR}'   #統計以冒號分隔的文字段落數,END{}語句塊中,往往會放入列印結果等語句

2、統計使用bash 的使用者個數

awk -F: '/bash$/{print | "wc -l"}' /etc/passwd   #呼叫wc -1命令統計使用bash 的使用者個數,等同於grep -c "bash$" /etc/passwd

3、檢視記憶體使用百分比

free -m | awk '/Mem:/ {print int($3/($3+$4)*100)"%"}'  #檢視當前 記憶體使用百分比

4、檢視當前CPU空閒率

top -b -n 1| grep cpu | awk-F ',' '{print$4}'| awk '{print$1}'   # 檢視當前CPU空閒率,(-b-n 1 表示只需要1次的輸出結果)

5、顯示上次系統重啟時間

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"的時間格式

6、呼叫w命令,並用來統計線上使用者數

awk 'BEGIN {n=0 ; while ("w" | getline) n++ ; {print n-2}}' #呼叫w命令,並用來統計線上使用者數

7、呼叫hostname,並輸出當前主機名

awk 'BEGIN {"hostname" | getline ; {print $0}}'  #呼叫hostname, 並輸出當前的主機名

8、cpu使用率

CPU使用率

cpu_us=`top -b -n 1 | grep Cpu | awk '{print $2}'`
cpu_sy=`top -b -n 1 | grep Cpu | awk -F ',' '{print $2}' | awk '{print $1}'`
cpu_sum=$(($cpu_us+$cpu_sy))
echo $cpu_sum
  • 當getline左右無重定向符“<”或“1”時,awk首先讀取到了第一行,就是1,然後getline, 就得到了1下面的第二行,就是2,因為getline之後,awk會改變對應的NF, NR, FNR和$0等內部變數,所以此時的$0的值就不再是1,而是2了,然後將它打印出來
  • 當getline左右有重定向符“<”或“|”時,getline則作用於定向輸入檔案,由於該檔案是剛開啟,並沒有被awk讀入一行,只是getline讀入,那麼getline返回的是該檔案的第一 行,而不是隔行
seq 10 | awk '{getline; print $0}'
seq 10 | awk '{print $0; getline}'

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

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

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

awk '{ip[$1]++}END{for(i in ip) {print ip[i],i}}' /var/log/httpd/access_log | sort -r

備註:定義陣列,陣列名稱為ip,數字的下標為日誌檔案的第1列(也就是客戶端的IP地址),++的目的在於對客戶端進行統計計數,客戶端.
IP出現一次計數器就加1。END中的指令在讀取完檔案後執行,通過迴圈將所有統計資訊輸出,for 迴圈遍歷的是陣列名ip的下標

六、CPU負載、記憶體容量等指令碼

  • cpu負載,記憶體容量,硬碟空間,網絡卡流量,安裝的軟體包數量,賬戶數量,當前登入的賬戶數量,程序數量,輸錯密碼的主機
uptime, free -m,df -h, ifconfig ens33, rpm -qa|wc -l, /etc/passwd, who,ps aux, /var/log/secure

缺實驗