awk:報告生成工具,能夠將文本處理爲比較直觀理想的報表。主要是對文本結果的格式化,也能處理文本搜索,但是效率要比grep低的多的多。
用法格式:
awk [options] 'script' file1,file2 . . . 'PATTERN{ action }'
一、分隔符:字段分隔符,行分隔符
-F: 輸入分隔符,下面以:號爲分隔符。
[root@node1 ~]# awk -F: '{print $1,$7}' /etc/passwd root /bin/bash bin /sbin/nologin daemon /sbin/nologin adm /sbin/nologin lp /sbin/nologin sync /bin/sync shutdown /sbin/shutdown halt /sbin/halt mail /sbin/nologin uucp /sbin/nologin operator /sbin/nologin games /sbin/nologin gopher /sbin/nologin ftp /sbin/nologin nobody /sbin/nologin
BEGIN模式:正式awk處理文本之前做一些準備工作。#必須在awk處理之前
[root@node1 ~]# awk -F: 'BEGIN {print "Username Shell"} {print $1,$7}' /etc/passwd Username Shell root /bin/bash bin /sbin/nologin daemon /sbin/nologin adm /sbin/nologin lp /sbin/nologin sync /bin/sync shutdown /sbin/shutdown halt /sbin/halt mail /sbin/nologin uucp /sbin/nologin operator /sbin/nologin games /sbin/nologin gopher /sbin/nologin
[root@node1 ~]# awk 'BEGIN {FS=":"} {print $1,$7}' /etc/passwd root /bin/bash bin /sbin/nologin daemon /sbin/nologin adm /sbin/nologin lp /sbin/nologin sync /bin/sync shutdown /sbin/shutdown halt /sbin/halt mail /sbin/nologin uucp /sbin/nologin operator /sbin/nologin games /sbin/nologin gopher /sbin/nologin ftp /sbin/nologin nobody /sbin/nologin
OFS:輸出格式,OFS=***** 輸出格式如下:
[root@node1 ~]# awk 'BEGIN {FS=":"; OFS="*****"} {print $1,$7}' /etc/passwd root*****/bin/bash bin*****/sbin/nologin daemon*****/sbin/nologin adm*****/sbin/nologin lp*****/sbin/nologin sync*****/bin/sync shutdown*****/sbin/shutdown halt*****/sbin/halt mail*****/sbin/nologin uucp*****/sbin/nologin operator*****/sbin/nologin games*****/sbin/nologin gopher*****/sbin/nologin ftp*****/sbin/nologin nobody*****/sbin/nologin
END模式:
[root@node1 ~]# awk 'BEGIN {FS=":"; OFS=":"} {print $1,$7} END{print "=========END=========="}' /etc/passwd root:/bin/bash bin:/sbin/nologin daemon:/sbin/nologin adm:/sbin/nologin lp:/sbin/nologin sync:/bin/sync shutdown:/sbin/shutdown halt:/sbin/halt mail:/sbin/nologin uucp:/sbin/nologin operator:/sbin/nologin games:/sbin/nologin gopher:/sbin/nologin ftp:/sbin/nologin nobody:/sbin/nologin vcsa:/sbin/nologin saslauth:/sbin/nologin postfix:/sbin/nologin sshd:/sbin/nologin nginx:/sbin/nologin apache:/sbin/nologin =========END==========
完善一下
[root@node1 ~]# awk 'BEGIN {FS=":"; OFS=":"; print "Username Shell"} {print $1,$7} END{print "=========END=========="}' /etc/passwd Username Shell root:/bin/bash bin:/sbin/nologin daemon:/sbin/nologin adm:/sbin/nologin lp:/sbin/nologin sync:/bin/sync shutdown:/sbin/shutdown halt:/sbin/halt mail:/sbin/nologin uucp:/sbin/nologin operator:/sbin/nologin games:/sbin/nologin gopher:/sbin/nologin ftp:/sbin/nologin nobody:/sbin/nologin vcsa:/sbin/nologin saslauth:/sbin/nologin postfix:/sbin/nologin sshd:/sbin/nologin nginx:/sbin/nologin apache:/sbin/nologin =========END==========
NF顯示字段:
[root@node1 ~]# df -lh |awk '{print NF}' 7 1 5 6 6
二、正則表達式:/PATERN/只匹配符合條件的行。
例:顯示以sh結尾的行
[root@node1 ~]# awk 'BEGIN {FS=":"; OFS=":"; print "Username Shell"} /sh$/ {print $1,$7} END{print "=========END=========="}' /etc/passwd Username Shell root:/bin/bash =========END==========
表達式:>, <,>-,<=,~,!~
匹配ID號大於50的賬號
[root@node1 ~]# awk -F: '$3>=50 {print $1,$3}' /etc/passwd nobody 99 vcsa 69 saslauth 499 postfix 89 sshd 74 nginx 498
匹配/bin/bash賬號
[root@node1 ~]# awk -F: '$7~/bash/ {print $1,$3}' /etc/passwd root 0 test1 500 test2 501
不匹配/bin/bash賬號
[root@node1 ~]# awk -F: '$7!~/bash/ {print $1,$3}' /etc/passwd bin 1 daemon 2 adm 3 lp 4 sync 5 shutdown 6 halt 7 mail 8 uucp 10 operator 11 games 12 gopher 13 ftp 14 nobody 99 vcsa 69 saslauth 499 postfix 89 sshd 74 nginx 498 apache 48
三、printf
printf命令的使用格式:
printf fromat,item1,item2...
要點:
1、其與print命令的最大不同是,printf所需要指定format;
2、format用於指定後面的每個item的輸出格式;
3、printf語句不會自動打印換行符;\n
format格式的指示符都以%開頭,後跟一個字符;如下:
%c;顯示字符的ASCII碼;
%d,%i;十進制整數;
%e,%E;科學計數法數值;
%f;顯示浮點數;
%g,%G;以科學計數法的格式或浮點格式顯示數值;
%s;顯示字符串;
%u:無符號整數;
%%;顯示%自身;
修飾符:
N:顯示寬度;
-:左對齊;
+:顯示數值符號;
例子
[root@node1 ~]# awk -F: '{printf "%15s %i\n",$1,$3}' /etc/passwd root 0 bin 1 daemon 2 adm 3 lp 4 sync 5 shutdown 6 halt 7 mail 8 uucp 10 operator 11 games 12 gopher 13 ftp 14 nobody 99 vcsa 69 saslauth 499 postfix 89 sshd 74 nginx 498 apache 48 test1 500 test2 501
%u顯示無符號整數,-%15s左對齊
[root@node1 ~]# awk -F: '{printf "%-15s %u\n",$1,$3}' /etc/passwd root 0 bin 1 daemon 2 adm 3 lp 4 sync 5 shutdown 6 halt 7 mail 8 uucp 10 operator 11 games 12 gopher 13 ftp 14 nobody 99 vcsa 69 saslauth 499 postfix 89 sshd 74 nginx 498 apache 48 test1 500 test2 501
五、算術操作符:
-x:負值
+x:轉換爲數值:
x^y;
x**y 次方
x*y 乘法
x/y
x+y
x-y;
x%y
賦值操作符:
=
+=
-=
*=
/=
%=
^=
**=
++
--
需要注意的是,如果其模式爲=號,此時使用/*/可能會有語法錯誤,應以/[=]/替代;
布爾值
awk 中任何非0值或非空字符串爲真,反之就爲假:
比較操作符
x<y True if x is less than y.
x<=y True if x less than or equal to y.
x>y True if x is greater than y.
x>=y True if x is greater than or equal to y.
x==y True if x is equal to y.
x!=y True if x is not equal to y .
x~y True if the string x matches the regexp denoted by y.
x!~y True if the string x does not match the regexp dented by y.
表達式建的邏輯關係符:
&&
||
例:顯示ID號大於500並且是/bin/bash的賬號。
[root@node1 ~]# awk -F: '$3>=500 &&$7~/bash/ {printf "%-15s %i %s\n ",$1,$3,$7}' /etc/passwd test1 500 /bin/bash test2 501 /bin/bash
條件表達式:
selector?if-true-exp:if-false-exp
if selector;then
if-true-exp
else
if-false-exp
fi
函數調用:
function_name(para1,para2)
六、常用的模式類型:
1、Regexp:正則表達式,格式爲/regular expression/
2、expression:表達式,其值非0或爲空字符時滿足條件,如:$1 ~/foo/ 或$1=="abc",用運算符~(匹配)和!~(不匹配)。
3、Ranges:指定的匹配範圍,格式爲Pat1,Pat2
4、BEGIN/END:特殊模式,僅在awk命令執行前一次或結束前運行一次。
5、Empty(空模式):匹配任意輸入行;
常見的Action
1、Expression;
2、Control statements
3、Compound statements
4、Input statements
5、Output statements
/正則表達式/:使用通配符的擴展集
關係表達式:可以用下面運算符進行操作,可以是字符或數字比較,如$2>$1選擇第二個字段比第一個字段長的行。
模式匹配表達式:
模式:指定一個行的範圍,改語法不能包括BEGIN和END模式。
例:打印abc開始到aaa結束所匹配的行內容
[root@node1 ~]# cat test1.sh mmm opq abc 1 cde 2 aaa 3 mnt 4 abc 5 hello 6 are 7 aaa 8 haow 9 are 10 you 11 abc 12 hello 13 world 14 [root@node1 ~]# awk '/abc/,/aaa/ {print $0}' test1.sh abc 1 cde 2 aaa 3 abc 5 hello 6 are 7 aaa 8 abc 12 hello 13 world 14
七、控制語句:
if-else
語法:if(condition){then-body} else {[ else-body ]}
例子:如果用戶的ID號是0,就是管理員。否則就是普通用戶
[root@node1 ~]# awk -F: '{if ($1=="root") print $1, "Admin";else print $1,"Common User"}' /etc/passwd root Admin bin Common User daemon Common User adm Common User lp Common User sync Common User shutdown Common User halt Common User mail Common User uucp Common User operator Common User games Common User gopher Common User ftp Common User nobody Common User vcsa Common User saslauth Common User postfix Common User sshd Common User nginx Common User apache Common User test1 Common User test2 Common User
顯示ID號大於500的用戶總數
[root@node1 ~]# awk -F: -v sum=0 '{if ($3>=500) sum++} END{print sum}' /etc/passwd 2
while
語法:while (condition) {statement1;statment2;...}
主要目的是每一個片中進行循環,不是每一行哦。
[root@node1 ~]# awk -F: '{i=1;while (i<3) {print $i;i++}}' /etc/passwd root x bin x daemon x adm x lp x sync x shutdown x halt x mail x uucp x operator x games x gopher x ftp x nobody x vcsa x saslauth x postfix x sshd x nginx x apache x test1 x test2 x
[root@node1 ~]# awk -F: '{i=1;while (i<=NF) {if (length($i)>=4) {print $i};i++}}' /etc/passwd root root /root /bin/bash /bin /sbin/nologin daemon daemon /sbin /sbin/nologin /var/adm /sbin/nologin /var/spool/lpd /sbin/nologin sync sync /sbin /bin/sync shutdown shutdown /sbin /sbin/shutdown halt halt /sbin /sbin/halt mail mail /var/spool/mail /sbin/nologin uucp uucp /var/spool/uucp /sbin/nologin operator operator /root /sbin/nologin games games /usr/games /sbin/nologin gopher gopher /var/gopher /sbin/nologin FTP User /var/ftp /sbin/nologin nobody Nobody /sbin/nologin vcsa virtual console memory owner /dev /sbin/nologin saslauth "Saslauthd user" /var/empty/saslauth /sbin/nologin postfix /var/spool/postfix /sbin/nologin sshd Privilege-separated SSH /var/empty/sshd /sbin/nologin nginx Nginx web server /var/lib/nginx /sbin/nologin apache Apache /var/www /sbin/nologin test1 /home/test1 /bin/bash test2 /home/test2 /bin/bash
[root@node1 ~]# awk -F: '{i=1;while (i<=3) {printf "%s", $i;i++;};printf "\n"}' /etc/passwd rootx0 binx1 daemonx2 admx3 lpx4 syncx5 shutdownx6 haltx7 mailx8 uucpx10 operatorx11 gamesx12 gopherx13 ftpx14 nobodyx99 vcsax69 saslauthx499 postfixx89 sshdx74 nginxx498 apachex48 test1x500 test2x501
打印大於100的數值,每行顯示
[root@node1 ~]# cat test2.sh 89 746 38 8489 99 55 34 857 7384 75492 88 56 13 83 [root@node1 ~]# awk '{i=1;while (i<=NF) {if ($i>=100) print $i;i++}}' test2.sh 746 8489 857 7384 75492
do-while
語法:do{statemenet1,statement2,...} while(condition)
先執行一次,不管條件滿足與否至少執行一次循環體。
[root@node1 ~]# awk -F: '{i=1;do {print $i;i++}while(i<=3)}' /etc/passwd
for
語法:for (variable assignment;condition;iteration process) {statement1,statement2,...}
[root@node1 ~]# awk -F: '{for(i=1;i<3;i++) print $i}' /etc/passwd root x bin x daemon x adm x lp x sync x shutdown
[root@node1 ~]# awk -F: '{for(i=1;i<NF;i++) {if (length($i)>=4) {print $i}}}' /etc/passwd root root /root /bin daemon daemon /sbin /var/adm /var/spool/lpd sync sync /sbin shutdown shutdown /sbin halt halt /sbin mail mail /var/spool/mail uucp uucp /var/spool/uucp operator operator /root games games /usr/games gopher gopher /var/gopher
八、awk數組:
數組:一組連續的可存多個值內存空間。關聯數組
例子:統計每個shell類型的次數。
$NF!~最後一個字段不爲空/^$/ (A IN BASH) 遍歷每一組數組的下標。
如A=[sbin/shutdown] 第二次A=[/bin/bash]...
BASH[A] 顯示數組的次數。
[root@node1 ~]# awk -F: '$NF!~/^$/{BASH[$NF]++}END{for (A in BASH){printf "%15s:%i\n",A,BASH[A]}}' /etc/passwd /sbin/shutdown:1 /bin/bash:3 /sbin/nologin:17 /sbin/halt:1 /bin/sync:1
例:netstat統計State爲TCP的狀態
[root@node1 ~]# netstat -tanl |awk '/^tcp/ {state[$NF]++}END{for (S in state) print S,state[S]}' ESTABLISHED 1 LISTEN 4
例:統計httpd日誌中訪問的IP次數
[root@rmt logs]# awk '{ip[$1]++} END {for (A in ip) print A,ip[A]}' access_log 192.168.254.50 1 192.168.254.60 91 192.168.254.220 9 192.168.254.56 9 192.168.254.66 43 192.168.254.57 96 192.168.254.58 7
九、awk的內置函數
split(string,array [,fieldsep[,seps] ])
功能:將string表示的字符串以fieldsep爲分隔,並將分割後的結果保存至array爲名的數組中:數組下標爲從1開始的序列:
length([string])
功能:返回string字符串字符的個數
substr(string,start[,length])
功能:取string字符串中的子串,從start開始,取length個;start從1開始計數:
[root@rmt logs]# netstat -ant |awk '/:80\>/{split($5,clients,":");IP[clients[4]]++}END{for (i in IP){print IP[i],i}}'|sort -rn |head -50 3
例:查找分區大於%20的文件系統
[root@rmt-app1 logs]# df -lh Filesystem Size Used Avail Use% Mounted on /dev/xvda1 20G 2.2G 17G 12% / tmpfs 16G 0 16G 0% /dev/shm /dev/xvdb1 493G 333G 135G 72% /usr/local [root@rmt-app1 logs]# df -lh |awk '!/^File/{split ($5,percent,"%"); if(percent[1]>=20){print $1}}' /dev/xvdb1
Linux Web服務器網站故障分析常用的命令
系統連接狀態篇:
1.查看TCP連接狀態 netstat -nat |awk ‘{print $6}’|sort|uniq -c|sort -rn netstat -n | awk ‘/^tcp/ {++S[$NF]};END {for(a in S) print a, S[a]}’ 或 netstat -n | awk ‘/^tcp/ {++state[$NF]}; END {for(key in state) print key,"\t",state[key]}’ netstat -n | awk ‘/^tcp/ {++arr[$NF]};END {for(k in arr) print k,"t",arr[k]}’ netstat -n |awk ‘/^tcp/ {print $NF}’|sort|uniq -c|sort -rn netstat -ant | awk ‘{print $NF}’ | grep -v ‘[a-z]‘ | sort | uniq -c
2.查找請求數請20個IP(常用於查找攻來源):
netstat -anlp|grep 80|grep tcp|awk ‘{print $5}’|awk -F: ‘{print $1}’|sort|uniq -c|sort -nr|head -n20 netstat -ant |awk ‘/:80/{split($5,ip,":");++A[ip[1]]}END{for(i in A) print A[i],i}’ |sort -rn|head -n20
3.用tcpdump嗅探80端口的訪問看看誰最高
tcpdump -i eth0 -tnn dst port 80 -c 1000 | awk -F"." ‘{print $1"."$2"."$3"."$4}’ | sort | uniq -c | sort -nr |head -20
4.查找較多time_wait連接
netstat -n|grep TIME_WAIT|awk ‘{print $5}’|sort|uniq -c|sort -rn|head -n20
5.找查較多的SYN連接
netstat -an | grep SYN | awk ‘{print $5}’ | awk -F: ‘{print $1}’ | sort | uniq -c | sort -nr | more
6.根據端口列進程
netstat -ntlp | grep 80 | awk ‘{print $7}’ | cut -d/ -f1
網站日誌分析篇1(Apache):
1.獲得訪問前10位的ip地址
cat access.log|awk ‘{print $1}’|sort|uniq -c|sort -nr|head -10 cat access.log|awk ‘{counts[$(11)]+=1}; END {for(url in counts) print counts[url], url}’
2.訪問次數最多的文件或頁面,取前20
cat access.log|awk ‘{print $11}’|sort|uniq -c|sort -nr|head -20
3.列出傳輸最大的幾個exe文件(分析下載站的時候常用)
cat access.log |awk ‘($7~/.exe/){print $10 " " $1 " " $4 " " $7}’|sort -nr|head -20
4.列出輸出大於200000byte(約200kb)的exe文件以及對應文件發生次數
cat access.log |awk ‘($10 > 200000 && $7~/.exe/){print $7}’|sort -n|uniq -c|sort -nr|head -100
5.如果日誌最後一列記錄的是頁面文件傳輸時間,則有列出到客戶端最耗時的頁面
cat access.log |awk ‘($7~/.php/){print $NF " " $1 " " $4 " " $7}’|sort -nr|head -100
6.列出最最耗時的頁面(超過60秒的)的以及對應頁面發生次數
cat access.log |awk ‘($NF > 60 && $7~/.php/){print $7}’|sort -n|uniq -c|sort -nr|head -100
7.列出傳輸時間超過 30 秒的文件
cat access.log |awk ‘($NF > 30){print $7}’|sort -n|uniq -c|sort -nr|head -20
8.統計網站流量(G)
cat access.log |awk ‘{sum+=$10} END {print sum/1024/1024/1024}’
9.統計404的連接
awk ‘($9 ~/404/)’ access.log | awk ‘{print $9,$7}’ | sort
10. 統計http status
cat access.log |awk ‘{counts[$(9)]+=1}; END {for(code in counts) print code, counts[code]}' cat access.log |awk '{print $9}'|sort|uniq -c|sort -rn
10.蜘蛛分析,查看是哪些蜘蛛在抓取內容。
/usr/sbin/tcpdump -i eth0 -l -s 0 -w - dst port 80 | strings | grep -i user-agent | grep -i -E 'bot|crawler|slurp|spider'
網站日分析2(Squid篇)按域統計流量
zcat squid_access.log.tar.gz| awk '{print $10,$7}' |awk 'BEGIN{FS="[ /]"}{trfc[$4]+=$1}END{for(domain in trfc){printf "%st%dn",domain,trfc[domain]}}'
數據庫篇
1.查看數據庫執行的sql
/usr/sbin/tcpdump -i eth0 -s 0 -l -w - dst port 3306 | strings | egrep -i 'SELECT|UPDATE|DELETE|INSERT|SET|COMMIT|ROLLBACK|CREATE|DROP|ALTER|CALL'
系統Debug分析篇
1.調試命令
strace -p pid
2.跟蹤指定進程的PID
gdb -p pid