溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

awk的使用---業務需求

發布時間:2020-07-20 04:20:03 來源:網絡 閱讀:943 作者:cuizhiliang 欄目:編程語言

awk是按照流來處理的,所以處理1-5G的文本數據相對還是可以的!


求和

awk -F : -v sum=0 '{sum+=$3} END{print sum}' /etc/passwd


或者 

awk -F :   '{sum+=$3} END{print sum}' /etc/passwd

默認變量為0


規定日志格式

$17 domainname

$19 request

$21 為響應狀態碼

應用1: 匹配統計F5日志中,含有某個域名的數量


可以按照以下方法來套

[root@CentOS-6-121 scripts]# awk -F:  '$1=="root" {print $0}' /etc/passwd | wc -l
1


對以上進行改版,因為統計的時候利用了wc -l 進行了,現在不需要wc -l ,awk完成統計

[root@CentOS-6-121 scripts]# awk -F:  -v n=0 '{if($1=="root") n++;}  END{print n}' /etc/passwd 
1


-v 可以指定變量,在 awk ''中利用變量的時候直接使用,不需要"$n" 這個地方要區別shell


注意: 以下語句,默認不指定n變量的時候,雖然可以出結果,是因為在n++的時候會默認設置n為0,但是這樣會出現bug,當沒有匹配的時候,去大于n的時候就不是0而是空

[root@CentOS-6-121 scripts]# awk -F:   '{if($1=="root") n++;}  END{print n}' /etc/passwd 
1


bug:

[root@CentOS-6-121 scripts]# awk -F:   '{if($1=="rooot") n++;}  END{print n}' /etc/passwd 

[root@CentOS-6-121 scripts]#



應用2: 使用shell中的變量和定義多變量 和邏輯運算符

&& 邏輯與

|| 邏輯或

! 否

~ 匹配字符串  !~  不匹配后面更正則表達式

-v key1=value1 -v key2-values



引用變量兩種方式

1

name="John"

  -v myname=$name '{print myname}'



在awk中我們可以通過“’$變量名’”的方式讀取sell scrpit程序中的變量。

name="John"

awk '{print $1,$2,"'$name'"}'  flil


原型:

awk -v t=0 -v domain="$domain" -v request="/main/detail" -v code=500  '$17==domain && $19 ~ request && $21 ==code {t++} END{print t}' access.log

0


測試語句:


[root@CentOS-6-121 scripts]# awk -F: '$1=="root" && $3==0 {print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash



awk -F:  '$1 =="root" || $1=="nobody" {print $1 "\t"$3}' /etc/passwd

nobody-2

root0



awk -F:  '$NF != "/bin/bash"  {print $1 "\t" $NF}' /etc/passwd




匹配:

awk '$NF !~ "/sbin/no*" {print $1" " $3}' /etc/passwd 

awk '$NF !~ /sbin\/no*/ {print $1" " $3}' /etc/passwd  (使用 ~ /express/ 是man awk 中正規的寫法)





注意:

判斷匹配的方法:

 1)$n~正則表達式

 2)if($n~正則表示式) print $


如果你的awk中使用了 BEGIN語句,就一定要使用 if 不能使用模式匹配,否則報錯

如:

報錯:

[root@CentOS-6-121 scripts]# awk -F: '$1=="root" && $3==0 BEGIN{n=0} {n++} END{print n}' /etc/passwd

awk: $1=="root" && $3==0 BEGIN{n=0} {t++} END{print t}

awk:                     ^ syntax error



改為:

[root@CentOS-6-121 scripts]# awk -F: 'BEGIN{n=0} {if($1 =="root" && $3==0)n++} END{print n}' /etc/passwd
1

使用變量:
[root@master ~]# n=1000
[root@master ~]# awk -v n=$n -F: '$3==n {print $1" "$3}' /etc/passwd
elasticsearch 1000




應用3: awk中的數組

awk -F : '{bash_array[$NF]++} END {for(i in bash_array) {print i,bash_array[i]}}' /etc/passwd


/bin/nologin 1

/sbin/shutdown 1

/bin/false 1

/bin/bash 11

/sbin/nologin 28

/sbin/halt 1

/bin/sync 1




3 指定域名的

[root@shnh-bak001 f5-log]$ awk '$17 =="gold.dianpingfang.com" {++domain[$21]} END {for(k
in domain) print k,domain[k]}' access.log

 2

200 4498

301 2

500 15

302 321

304 2




應用四:統計目錄下的一部分目錄的數據大小

du -s stu* | awk '{sum=sum+$1} END{print sum}'



數據庫的連接情況

netstat -tanp |awk '/3306/ {print $5}'  |awk -F ":" '{a[$1]++}END{for (i in a) print a[i],i}'  |sort -nr



應用五:行范圍指定

AWK 的匹配模式種類:

 Patterns

       AWK patterns may be one of the following:


              BEGIN

              END

              /regular expression/

              relational expression

              pattern && pattern

              pattern || pattern

              pattern ? pattern : pattern

              (pattern)

              ! pattern

              pattern1, pattern2


awk -F : '{print $NF":"$2":"$3":"$4":"$5":"$6":"$1 > "/tmp/oldboy/passwd"}' /tmp/oldboy/passwd


打印第2、3、4、5行

sed -n "2,5p" /etc/passwd

awk "NR==2,NR==5" /etc/passwd

awk "NR>1&&NR<6" /etc/passwd

cat /etc/passwd | head -5 | tail -4



實例:

 awk -F: 'NR==2,NR==5 {print $1}' /etc/passwd

awk -F: 'NR>1 && NR<6{print $1}' /etc/passwd 




案例6: 打印awk第一次匹配到的關鍵字,之后的所有行!


分兩步,第一找出第一次匹配的行,匹配nobody賬號

awk -F ":" '{if($1 ~ "nobody") print NR;}' passwd

15

25


思考,如何只匹配到一次后,就退出awk繼續向下匹配而直接退出查找。

改良:


awk -F ":" '{if($1== "nobody") {print NR; exit 0}}' passwd

15

第二: 打印第15行之后的所有行

awk -F ":" '{if(NR > 15) print $0;}' passwd


或者(以下行范圍更適用)

awk -F: 'NR>15{print $1}' /etc/passwd     


可以提高難道綜合成一條awk語句

awk -F ":" '{if($1== "nobody") {a=NR}} {if(NR>a && a!=0) print $0}' passwd


為什么要做一個a!=0 的條件,因為沒有匹配到nobody的時候,未定義賦值過的變量再awk中默認值為0。


 


案例七: awk中調用系統命令

awk -F ":" '{if($1== "nobody") {system("echo this is noboy user")}} ' passwd

或者: $1=="root" 字符串一定要用引號引起來,不然在awk里面就是變量拉


awk -F ":" '$1=="root" {system("echo this is noboy user")} ' /etc/passwd



案例7: awk多分隔符切,分隔符為[ 

rabbitmq的集群狀態 partitions行  {partitions,[]}]  如果[] 中有內容i表示集群不正常。

if [ "x" != "x$(sudo /usr/sbin/rabbitmqctl cluster_status |grep partitions |awk -F '[\\[\\]]'  '{print $2}')" ];then echo 0;else echo 1;fi



案例8:  統計nf(iptables 跟蹤鏈表中 各協議的數量)


awk '{a[$3]++ } END{for (k in a) print k,a[k]}' /proc/net/nf_conntrack

tcp 11

udp 26

icmp 1






案例7. 使用split內置函數進行分割

tac  haproxy.log  | awk '{
                                        split($6,a,":")
                                        if(a[1]~"05/Mar/2017"){ 
                                            print $0
                                        }
                                        if(a[1]~"04/Mar/2017"){exit}
                                }' >> ./a_access.log 
exit



案例8: 打印匹配的行并 輸出文件名

awk '/root/{print FILENAME "-----"$0}' /etc/passwd



#FILENAME 是默認變量,或者使用grep實現

grep -H root /etc/passwd


#-H 是顯示文件名在匹配的行前面




內置函數的使用

split的用法:

一、split 初始化和類型強制 
       awk的內建函數split允許你把一個字符串分隔為單詞并存儲在數組中。你可以自己定義域分隔符或者使用現在FS(域分隔符)的值。
格式:

   split (string, array, field separator)
    split (string, array)  -->如果第三個參數沒有提供,awk就默認使用當前FS值。


例2:計算指定范圍內的和(計算每個人1月份的工資之和)

1
2
3
4
5
6
7
8
9
10
[root@test ~]# cat test.txt
Tom    2012-12-11      car     53000
John   2013-01-13      bike    41000
vivi    2013-01-18      car     42800
Tom    2013-01-20      car     32500
John   2013-01-28      bike    63500
[root@test ~]# awk '{split($2,a,"-");if(a[2]==01){b[$1]+=$4}}END{for(i in b)print i,b[i]}' test.txt  
vivi 2800
Tom2500
John4500



2. gsub的函數

替換正則表達式的內容

 gsub(r, s [, t])        For each substring matching the regular expression r in the string  t,sub-stitute  the  string s。

t字符串中匹配r正則的替換成s字符串。

r: 正則表達式

s:字符串

t,如果省略就是 $0.



awk '$0 ~ /6.8/ {gsub("6.8", "6.6", $0); print $0}' /etc/issue


將最后一行為nologin的替換成 /bin/bash

 awk -F: '{gsub(".*nologin","/bin/bash",$NF) ;print $NF}' /etc/passwd



3.  length()函數

length([s]) 

返回字符串的長度,如果s沒有提供,默認是$0。

[root@cuizhiliang ~]# cat /etc/issue |awk '{print length($2)}'                               

7

2

0


#分析文本中每行的字符大小 找到很長的那一行

[root@cuizhiliang ~]# cat /etc/issue |awk '{print length()}'    

26

18

0



4 文本處理 大小寫轉換函數 toupper(string), tolower(string)

awk -F: 'NR==1,NR==2{print toupper($NF)}' /etc/passwd 

/BIN/BASH

/SBIN/NOLOGIN



5 index函數

index(s, t)  

返回t中的字符串出現在s中的開始位置.從1開始的位置。若沒有則返回0

Returns the index of the string t in the string s, or 0 if t is not present.

(This implies that character indices start at one.)


[root@master ~]# awk 'BEGIN{print index("98765432123","23")}'

10





6 system 調用系統命令


重要的是調用系統給的命令的時候 參數適用awk的field字段。

head dfs.log | awk '{system("./purge_squid_url.sh " ""$0"")}'



arp -n|awk '/^[1-9]/{system("echo "$1)}'


arp -n| awk '/^[1-9]/{system("echo " ""$1"")}'


刪除所有的arp

arp -n|awk '/^[1-9]/{system("arp -d "$1)}'









向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女