文本三劍客之awk-從入門到入土

awk命令格式和選項

語法形式

awk [options] 'program' file…
Program:pattern{action statements;..}

命令選項

-F fs    fs指定輸入分隔符,fs可以是字符串或正則表達式,如-F:
-v var=value    賦值一個用戶定義變量,將外部變量傳遞給awk
-f scripfile   從腳本文件中讀取awk命令
-m[fr] val    對val值設置內在限制,-mf選項限制分配給val的最大塊數目;-mr選項限制記錄的最大數目。這兩個功能是Bell實驗室版awk的擴展功能,在標準awk中不適用。

模式 pattern

模式可以是以下任意一個:

  • /正則表達式/:使用通配符的擴展集。
  • 關係表達式:使用運算符進行操作,可以是字符串或數字的比較測試。
  • 模式匹配表達式:用運算符~(匹配)和!~(不匹配)。
  • BEGIN語句塊、pattern語句塊、END語句塊:參見awk的工作原理

awk腳本基本結構

awk 'BEGIN{ print "start" } pattern{ commands } END{ print "end" }' file

awk的工作原理

awk 'BEGIN{ commands } pattern{ commands } END{ commands }'
  • 第一步:執行BEGIN{ commands }語句塊中的語句;
  • 第二步:從文件或標準輸入(stdin)讀取一行,然後執行pattern{ commands }語句塊,它逐行掃描文件,從第一行到最後一行重複這個過程,直到文件全部被讀取完畢。
  • 第三步:當讀至輸入流末尾時,執行END{ commands }語句塊。

    BEGIN語句塊 在awk開始從輸入流中讀取行 之前 被執行,這是一個可選的語句塊,比如變量初始化、打印輸出表格的表頭等語句通常可以寫在BEGIN語句塊中。

    END語句塊 在awk從輸入流中讀取完所有的行 之後 即被執行,比如打印所有行的分析結果這類信息彙總都是在END語句塊中完成,它也是一個可選語句塊。

    pattern語句塊 中的通用命令是最重要的部分,它也是可選的。如果沒有提供pattern語句塊,則默認執行{ print },即打印每一個讀取到的行,awk讀取的每一行都會執行該語句塊。

    示例

echo -e "A line 1nA line 2" | awk 'BEGIN{ print "Start" } { print } END{ print "End" }'
Start
A line 1
A line 2
End

當使用不帶參數的print時,它就打印當前行,當print的參數是以逗號進行分隔時,打印時則以空格作爲定界符。在awk的print語句塊中雙引號是被當作拼接符使用,例如:

echo | awk '{ var1="v1"; var2="v2"; var3="v3"; print var1,var2,var3; }' 
v1 v2 v3

雙引號拼接使用:

echo | awk '{ var1="v1"; var2="v2"; var3="v3"; print var1"="var2"="var3; }'
v1=v2=v3

{ }類似一個循環體,會對文件中的每一行進行迭代,通常變量初始化語句(如:i=0)以及打印文件頭部的語句放入BEGIN語句塊中,將打印的結果等語句放在END語句塊中。

awk內置變量(預定義變量)

FS:字段分隔符等同-F

awk -v FS=':' '{print $1,FS,$3}’ /etc/passwd 
awk –F: '{print $1,$3,$7}’ /etc/passwd

OFS:輸出字段分隔符,默認爲空白字符

awk -v FS=‘:’ -v OFS=‘:’ '{print $1,$3,$7}’ /etc/passwd

RS:輸入記錄分隔符,指定輸入時的換行符

awk -v RS=' ' ‘{print }’ /etc/passwd 

ORS:輸出記錄分隔符,輸出時用指定符號代替換行符

awk -v RS=' ' -v ORS='###'‘{print }’ /etc/passwd

NF:字段數量

awk -F:‘{print NF}’ /etc/fstab 引用變量時,變量前不需加$ 
awk -F:‘{print $(NF-1)}' /etc/passwd 

NR:行數記錄號

awk ‘{print NR}’ /etc/fstab 
awk END‘{print NR}’ /etc/fstab

FNR:各文件分別計數,記錄號

awk '{print FNR}' /etc/fstab /etc/inittab 

FILENAME:當前文件名

awk '{print FILENAME}’ /etc/fstab 

ARGC:命令行參數的個數

awk '{print ARGC}’ /etc/fstab /etc/inittab 
awk ‘BEGIN {print ARGC}’ /etc/fstab /etc/inittab 

ARGV:數組,保存的是命令行所給定的各參數

awk ‘BEGIN {print ARGV[0]}’ /etc/fstab /etc/inittab 
awk ‘BEGIN {print ARGV[1]}’ /etc/fstab /etc/inittab

FILENAME當前⽂件名FILENAME變量的使⽤

awk '{print FILENAME,FNR,$1}' /etc/fstab /root/awktest.txt

自定義變量量(區分字符大小寫)
(1) -v var=value
(2) 在program中直接定義

將外部變量值傳遞給awk

awk -v test='hello gawk' '{print test}' /etc/fstab 
awk -v test='hello gawk' 'BEGIN{print test}' 
awk 'BEGIN{test="hello,gawk";print test}' 
awk -F:‘{sex=“male”;print $1,sex,age;age=18}’ /etc/passwd 
awk -F: -f awkscript script=“awk” /etc/passwd

查找進程pid

netstat -antup | grep 7770 | awk '{ print $NF NR}' | awk '{ print $1}'

操作符

比較操作符:
==, !=, >, >=, <=
模式匹配符:
~:左邊是否和右邊匹配,包含
!~:是否不匹配 示例:

awk -F: '$0 ~ /root/{print $1}‘ /etc/passwd 
awk '$0~“^root"' /etc/passwd 
awk '$0 !~ /root/‘ /etc/passwd 
awk -F: ‘$3==0’ /etc/passwd

邏輯操作符:
與&&,或||,非!
示例:

• awk -F: '$3>=0 && $3<=1000 {print $1}' /etc/passwd 
• awk -F: '$3==0 || $3>=1000 {print $1}' /etc/passwd 
• awk -F: ‘!($3==0) {print $1}' /etc/passwd 
• awk -F: ‘!($3>=500) {print $3}’ /etc/passwd 

運算級優先級表

!級別越高越優先
級別越高越優先

awk高級輸入輸出

讀取下一條記錄

awk中next語句使用:在循環逐行匹配,如果遇到next,就會跳過當前行,直接忽略下面語句。而進行下一行匹配。next語句一般用於多行合併:

cat text.txt
a
b
c
d
e

awk 'NR%2==1{next}{print NR,$0;}' text.txt
2 b
4 d

當記錄行號除以2餘1,就跳過當前行。下面的print NR,$0也不會執行。下一行開始,程序有開始判斷NR%2值。這個時候記錄行號是:2 ,就會執行下面語句塊:'print NR,$0'

分析發現需要將包含有“web”行進行跳過,然後需要將內容與下面行合併爲一行:

cat text.txt
web01[192.168.2.100]
httpd            ok
tomcat               ok
sendmail               ok
web02[192.168.2.101]
httpd            ok
postfix               ok
web03[192.168.2.102]
mysqld            ok
httpd               ok
0
awk '/^web/{T=$0;next;}{print T":t"$0;}' test.txt
web01[192.168.2.100]:   httpd            ok
web01[192.168.2.100]:   tomcat               ok
web01[192.168.2.100]:   sendmail               ok
web02[192.168.2.101]:   httpd            ok
web02[192.168.2.101]:   postfix               ok
web03[192.168.2.102]:   mysqld            ok
web03[192.168.2.102]:   httpd               ok

簡單地讀取一條記錄

awk getline用法:輸出重定向需用到getline函數。getline從標準輸入、管道或者當前正在處理的文件之外的其他輸入文件獲得輸入。它負責從輸入獲得下一行的內容,並給NF,NR和FNR等內建變量賦值。如果得到一條記錄,getline函數返回1,如果到達文件的末尾就返回0,如果出現錯誤,例如打開文件失敗,就返回-1。

getline語法:getline var,變量var包含了特定行的內容。

awk getline從整體上來說,用法說明:

  • 當其左右無重定向符|&lt;時: getline作用於當前文件,讀入當前文件的第一行給其後跟的變量var$0(無變量),應該注意到,由於awk在處理getline之前已經讀入了一行,所以getline得到的返回結果是隔行的。
  • 當其左右有重定向符|&lt;時: getline則作用於定向輸入文件,由於該文件是剛打開,並沒有被awk讀入一行,只是getline讀入,那麼getline返回的是該文件的第一行,而不是隔行。

    示例:

執行linux的date命令,並通過管道輸出給getline,然後再把輸出賦值給自定義變量out,並打印它:

awk 'BEGIN{ "date" | getline out; print out }' test

執行shell的date命令,並通過管道輸出給getline,然後getline從管道中讀取並將輸入賦值給out,split函數把變量out轉化成數組mon,然後打印數組mon的第二個元素:

awk 'BEGIN{ "date" | getline out; split(out,mon); print mon[2] }' test

命令ls的輸出傳遞給geline作爲輸入,循環使getline從ls的輸出中讀取一行,並把它打印到屏幕。這裏沒有輸入文件,因爲BEGIN塊在打開輸入文件前執行,所以可以忽略輸入文件。

awk 'BEGIN{ while( "ls" | getline) print }'

關閉文件

awk中允許在程序中關閉一個輸入或輸出文件,方法是使用awk的close語句。

close("filename")

filename可以是getline打開的文件,也可以是stdin,包含文件名的變量或者getline使用的確切命令。或一個輸出文件,可以是stdout,包含文件名的變量或使用管道的確切命令。

輸出到一個文件

awk中允許用如下方式將結果輸出到一個文件:

echo | awk '{printf("hello word!n") > "datafile"}'
或
echo | awk '{printf("hello word!n") >> "datafile"}'

控制語句:

{statements;...}:組合語句;
if(condition){statements;...}else {statements;...} 
if(condition1){statement1}else if(condition2){statement2} else{statement3} 
while(condition){statements;...} 
do {statements;...} while(condition)
for(expr1;expr2;expr3) {statements;...} 
break 
continue 
delete array[index] 
delete array 
exit
awk-F:'{$3>=500?usertype="commonuser":usertype="sysuser";printf"%-15s %-20s %10d\n",usertype,$1,$3}' /etc/passwd

數組的定義

數字做數組索引(下標):

Array[1]="sun"
Array[2]="kai"

字符串做數組索引(下標):

Array["first"]="www"
Array"[last"]="name"
Array["birth"]="1987"

使用中print Array[1]會打印出sun;使用print Array[2]會打印出kai;使用print["birth"]會得到1987。

讀取數組的值

{ for(item in array) {print array[item]}; }       #輸出的順序是隨機的
{ for(i=1;i<=len;i++) {print array[i]}; }         #Len是數組的長度

數組相關函數

得到數組長度:

awk 'BEGIN{info="it is a test";lens=split(info,tA," ");print length(tA),lens;}'
4 4

length返回字符串以及數組長度,split進行分割字符串爲數組,也會返回分割得到數組長度。

awk 'BEGIN{info="it is a test";split(info,tA," ");print asort(tA);}'
4

asort對數組進行排序,返回數組長度。

輸出數組內容(無序,有序輸出):

awk 'BEGIN{info="it is a test";split(info,tA," ");for(k in tA){print k,tA[k];}}'
4 test
1 it
2 is
3 a 

for…in輸出,因爲數組是關聯數組,默認是無序的。所以通過for…in得到是無序的數組。如果需要得到有序數組,需要通過下標獲得。

awk 'BEGIN{info="it is a test";tlen=split(info,tA," ");for(k=1;k<=tlen;k++){print k,tA[k];}}'
1 it
2 is
3 a
4 test

注意:數組下標是從1開始,與C數組不一樣。

內置函數

awk內置函數,主要分以下3種類似:算數函數、字符串函數、其它一般函數、時間函數。

算術函數

格式 描述
atan2( y, x ) 返回 y/x 的反正切。
cos( x ) 返回 x 的餘弦;x 是弧度。
sin( x ) 返回 x 的正弦;x 是弧度。
exp( x ) 返回 x 冪函數。
log( x ) 返回 x 的自然對數。
sqrt( x ) 返回 x 平方根。
int( x ) 返回 x 的截斷至整數的值。
rand( ) 返回任意數字 n,其中 0 <= n < 1。
srand( [expr] ) 將 rand 函數的種子值設置爲 Expr 參數的值,或如果省略 Expr 參數則使用某天的時間。返回先前的種子值。

舉例說明:

awk 'BEGIN{OFMT="%.3f";fs=sin(1);fe=exp(10);fl=log(10);fi=int(3.1415);print fs,fe,fl,fi;}'
0.841 22026.466 2.303 3

OFMT 設置輸出數據格式是保留3位小數。

獲得隨機數:

awk 'BEGIN{srand();fr=int(100*rand());print fr;}'
78
awk 'BEGIN{srand();fr=int(100*rand());print fr;}'
31
awk 'BEGIN{srand();fr=int(100*rand());print fr;}'
41 

格式化字符串輸出(printf使用)

格式化字符串格式:

其中格式化字符串包括兩部分內容:一部分是正常字符,這些字符將按原樣輸出; 另一部分是格式化規定字符,以"%"開始,後跟一個或幾個規定字符,用來確定輸出內容格式。

格式 描述 格式 描述
%d 十進制有符號整數 %u 十進制無符號整數
%f 浮點數 %s 字符串
%c 單個字符 %p 指針的值
%e 指數形式的浮點數 %x %X 無符號以十六進制表示的整數
%o 無符號以八進制表示的整數 %g 自動選擇合適的表示法
awk -F: ‘{printf "%s",$1}’ /etc/passwd 
awk -F: ‘{printf "%s\n",$1}’ /etc/passwd 
awk -F: '{printf "%-20s %10d\n",$1,$3}' /etc/passwd 
awk -F:‘ {printf "Username: %s\n",$1}’ /etc/passwd 
awk -F: ‘{printf “Username: %s,UID:%d\n",$1,$3}’ /etc/passwd 
awk -F: ‘{printf "Username: %15s,UID:%d\n",$1,$3}’ /etc/passwd 
awk -F: ‘{printf "Username: %-15s,UID:%d\n",$1,$3}’ /etc/passwd

練習實例

輸出當前所有用戶

awk -F: '{printf "user:%d ^C\n",NR,$1}' /etc/passwd

ssh連接數

ss -nt|awk -F "[[:space:]]+|:" 'NR>1{print $(NF-2)}'
ss -nt|awk -F "[[:space:]]+|:" 'NR!=1{print $(NF-2)}'

uid大於1000用戶

awk -F: '$3>=1000{print $1,$3}' /etc/passwd

本機ip地址

7
ifconfig ens33 |awk 'NR==2{print $2}'
6
ifconfig eth0 |awk -F"[[:space:]]+|:" 'NR==2{print $4}'

分區使用率

df|awk -F"[[:space:]]+|%" 'NR!=1{print $1,$5}'

df|awk -F"[[:space:]]+|%" 'NR!=1 && $5>10{print $1,$5}'
df|awk -F"[[:space:]]+|%" '/^\/dev\/sd/{print $1,$5}'
fstab
cat /etc/fstab |awk '!/^#|^$/{print $0}'

可登錄用戶

cat /etc/passwd |awk '!/nologin$/{print $0}'
cat /etc/passwd |awk '/nologin$/{print $0}'

⽂件ip_list.txt如下格式,請提取“.magedu.com"前⾯的主機名部分 並寫⼊到該⽂件中:

1 blog.magedu.com 
2 www.magedu.com 
... 
999 study.magedu.com
awk -F'[" ".]' '{print $2}' ip_list.txt >> ip_list.txt

統計/etc/fstab⽂件中每個⽂件系統類型出現的次數?

awk '/^[UUID\/]/{fs[$3]++}END{for(i in fs){print i,fs[i]}}' /etc/fstab 

統計/etc/fstab⽂件中每個單詞出現的次數?

awk '{for(i=1;i<=NF;i++){word[$i]++}}END{for(j in word){print j,word[j]}}' /etc/fstab 

提取出字符串Yd$C@M05MB%9Bdh7dq+YVixp3vpw中的所有數 字?

echo "yd$C@M05MB%9&Bdh7dq+yVixp3vpw" | awk 'gsub(/[^[:digit:]]/," ",$0)' 

有⼀⽂件記錄了1-100000之間的隨機的整數共5000個,存儲的格 式,100,50,35,89,。。。請取出其中最⼤和最⼩的整數?

]# (echo -e "$RANDOM\c";for((i=1;<100;i++));do echo -e “,$RANDOM\c”;done)i>num.txt
]#awk -F "," '{min=$1;max=$1;for(i=1;i<=NF;i++){if($i>=max){max=$i} else if(min>=$i)min=$i}print min,max}' num.txt

解決DOS***⽣產案例:根據web⽇志或⽹絡連接數,監控當某個ip 併發連接數或者短時間內pv達到100,即調⽤防⽕牆命令封掉對應的ip,控頻率每隔5分鐘;防⽕牆命令爲iptables -A INPUT -s IP -j REJECT?

vim deny_dos.sh 
while true ;do 
awk '/^[0-9]/{IP[$1]++}END{for(i in IP){if (IP[i]>=100)print i}}' 
/var/log/httpd/access_log | while read line;do iptables -A INPUT -s $line -j REJECT;done 
sleep 300
done

將以下⽂件內容中FQDN取出並根據其進⾏計數從⾼到低排序:

http://mail.magedu.com/index.html
http://www.magedu.com/test.html
http://study.magedu.com/index.html
http://blog.magedu.com/index.html
http://www.magedu.com/images/logo.jpg
http://blog.magedu.com/20080102.html
awk -F "[/]+" '{html[$2]++}END{for(i in html)print i,html[i]}' html.txt
答:awk -F “/” ‘{print $3}’|sort|uniq -c|sort -nr

將以下⽂本以inode爲標記,對inode相同的counts進⾏累加,並且統 計出 同一inode中,beginnumber的最小值和endnumber的最大值

inode|beginnumber|endnumber|counts|
106|3363120000|3363129999|10000|
106|3368560000|3368579999|20000|
310|3337000000|3337000100|101|
310|3342950000|3342959999|10000|
310|3362120960|3362120961|2|
311|3313460102|3313469999|9898|
311|3313470000|3313499999|30000|
311|3362120962|3362120963|2|
輸出的結果格式爲:
 310|3337000000|3362120961|10103|
 311|3313460102|3362120963|39900|
 106|3363120000|3368579999|30000| 
awk -F'|' -v OFS='|' '/^[0-9]/{inode[$1]++; if(!bn[$1]){bn[$1]=$2}else if(bn[$1]>$2){bn[$1]=$2}; if(en[$1]

#######################

⽂件datafile內容如下: 
Mike Harrington:[510] 548-1278:250:100:175
Christian Dobbins:[408] 538-2358:155:90:201
Suan Dalsass:[206] 654-6279:250:60:50
Archie McNichol:[206] 548-1348:250:100:175
Jody Savage:[206] 548-1278:15:188:150
Guy Quigley:[916] 343-6410:250:100:175
Dan Saveage:[406] 298-7744:450:300:275
Nancy McNeil:[206] 548-1278:250:80:75
John Goldenrod:[916] 348-4278:250:100:175
Chet Main:[510] 548-5258:50:95:135
Tom Savage:[408] 926-3456:250:168:200
Elizabeth Stachelin:[916] 440-1763:175:75:300

上面的數據表中包含名字、電話號碼和過去三個月裏的捐款,下面分別用awk解答:

1)顯示所有電話號碼? 
答:awk -F ":" '{print $2}' datafile.txt 
2)顯示Dan的電話號碼? 
答:awk -F ":" '/^Dan/{print $2}' datafile.txt 
3)顯示Suan的捐款和電話? 
答:awk -F ":" '/^Suan/{print $3,$4,$5,$2}' datafile.txt 
4)顯示所有以D開頭的姓? 
答:awk -F ":" '{print $1}' datafile.txt | awk '{print $2}'|awk '/^D/' 
5)顯示所有以一個C或E開頭的名? 
答:awk -F ":" '{print $1}' datafile.txt | awk '{print $1}'|awk '/^[CE]/'
6)顯示所有隻有四個字符的名? 
答:awk -F ":" '{print $1}' datafile.txt | awk '{if(length($1)==4)print $1}' 
7)顯示所有區號爲916的人名? 
答:awk -F ":" '/916/{print $1}' datafile.txt
8)顯示Mike的捐款,顯示每個值時都有$開頭,如$250$100$175? 
答:awk -F ":" '/^Mike/{print "$"$3"$"$4"$"$5}' datafile.txt 
9)顯示姓,其後跟一個逗號和名,如Jody,Savage? 
答:awk -F ":" '{print $1}' datafile.txt | awk '{print $2,",",$1}' 
10)寫一個awk的腳本,作用: 
(1)顯示Savage的全名和電話號碼 
(2)顯示Cher的捐款 
(3)顯示所有頭一個月捐款$250的人名 
答:vim awk #!/bin/awk -f 
BEGIN{FS=":"} 
{if($1 ~/Savage/) print $1":"$2}
{if($1~/^Chet/) print "$"$3":""$"$4":""$"$5}
{if($3==250) print $1} 
awk -f awk datafile.txt

⽂件名AccQryFree2016.log,存在⽬錄/root/boss/log/下,內容:

12:00:00 service start query_value,exited with value 0;
12:00:01 select * from crm_user where sts=1;exited with value 0;
12:10:01 use db:db_ngboss[srv_zw1] 12:20:00 service start query_value,exited with value 0;
12:22:01 select * from crm_user where sts=1;exited with value 0;
12:23:01 use db:db_ngboss[srv_zw1]
1)統計出文件中字符串exited with value 0出現的次數? 
答:grep -o "exited with value 0" AccQryFree2016.log|uniq -c 
2)使用vi編輯器,將文件中exited with value 0替換爲EXITED WITH VALUE 0? 
答:vim /root/boss/log/AccQryFree2016.log :%s/exited with value 0/EXITED WITH VALUE 0/g 
3)寫出帶有exited with value 0的時間列全部輸出? 
答:grep "exited with value 0" AccQryFree2016.log|awk -F " " ' {print $2}' 
4)把該文件壓縮? 
答:tar jcvf AccQryFree2016.log.tar.bz2 /root/boss/log/AccQryFree2016.log
5)配置一個定時任務,將該文件在每週五下午6點進行刪除? 
答:crontab -e 0 18 * * 5 rm -rf /root/boss/log/AccQryFree2016.log

使⽤netstat和awk統計服務器出現tcp⽹絡狀態並按數量排序?

netstat -tan |grep "^tcp\b" |awk '{print $5}' |sort | uniq -c| sort -nr

實現查詢⽂件file1⾥⾯空格開始的所在的⾏號?

答:grep -n -E '^[[:sapce:]] ' file1|awk -F: '{print $1}'

使⽤awk命令,計算⼀個⽬錄下⽂件⼤⼩的總和?

答:ll |awk 'BEGIN{sum=0}{sum=sum+$5}END{print sum}'

使⽤awk統計當前主機的併發訪問量?

答:netstat -tan | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}' 顯示結果: 
LAST_ACK 1 SYN_RECV 14 
ESTABLISHED 79 
FIN_WAIT1 28 
FIN_WAIT2 3 
CLOSING 5 
TIME_WAIT 1669 
解釋: 
CLOSED:無連接是活動的或正在進行 
LISTEN:服務器在等待進入呼叫 
SYN_RECV:一個連接請求已經到達,等待確認 
SYN_SENT:應用已經開始,打開一個連接 
ESTABLISHED:正常數據傳輸狀態 
FIN_WAIT1:應用說它已經完成 
FIN_WAIT2:另一邊已同意釋放 
ITMED_WAIT:等待所有分組死掉 
CLOSING:兩邊同時嘗試關閉 
TIME_WAIT:另一邊已初始化一個釋放 
LAST_ACK:等待所有分組死掉
統計apache訪問⽇志流量排名前10個ip? 
答: 
cat access_log | awk ’{print $1}’ | sort | uniq -c | sort -n -r | head -10
解法2: 
awk ‘{a[$1] += 1;} END {for (i in a) printf(“%d %s\n”, a[i], i);}’ 日誌文 件 | sort -n | tail

使⽤netstat -an輸出格式,請編寫腳本,統計輸出連接到本地主機 數最多的10個ip,並按連接數從多到少排序?
tcp 0 52 172.18.118.155:22 172.18.116.232:49916 ESTABLISHED
答:

#!/bin/sh 
top10ip=`ss -nt | grep 'ESTAB' | awk '{print $5}' | cut -d: -f1 | grep "^[[:digit:]]\+.*" | sort | uniq -c | sort -rnk1 | awk '{print $2,"\t",$1}' | head` 

echo "連接到本地主機最多的10個ip是:$top10ip"nginx的access.log⽇志如下,⽤shell實現,將狀態碼爲200的請求 的ip訪問排名前10個列出來:

172.18.116.232 - - [18/May/2018:00:20:29 -0400] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Safari/537.36" "-"
172.18.116.232 - - [18/May/2018:00:20:29 -0400] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Safari/537.36" "-"
答:awk '($9 ~ /200/)' access.log | awk '{print $9,$7}' | sort -nr |head -n10

統計apaceh的access.log中訪問量最多的5個ip?

172.18.116.232 - - [21/May/2018:05:29:11 -0400] "GET /favicon.ico HTTP/1.1" 404 209 "http://172.18.118.155:8080/" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Safari/537.36"
答: cat access_log | awk ’{print $1}’ | sort | uniq -c | sort -nr | head -5

awk實現打印奇數⾏和偶數⾏

偶數seq 10|awk '!(i=!i)'
奇數seq 10|awk 'i=!i'
等同於sed命令:
seq 10 | sed -n '1~2p'
seq 10 | sed -n '2~2p'

匹配以f開頭的⾏開始,到r開頭的⾏結束之間的所有⾏

awk '/^f/,/^r/' /etc/passwd

查找netstat -nt命令的結果中Foreign Address列的地址,統計每個地址鏈接的次數,如果⼤於2次, 顯⽰ip

netstat -nt |awk '/^tcp/{print $5}'|awk -F: '{print $1}'|sort |uniq -c|awk '$1>1{print $2}' 172.18.116.232
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章