awk進階

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章