awk是按照流來處理的,所以處理1-5G的文本數(shù)據(jù)相對(duì)還是可以的!
創(chuàng)新新互聯(lián),憑借10多年的網(wǎng)站建設(shè)、成都網(wǎng)站制作經(jīng)驗(yàn),本著真心·誠(chéng)心服務(wù)的企業(yè)理念服務(wù)于成都中小企業(yè)設(shè)計(jì)網(wǎng)站有上千多家案例。做網(wǎng)站建設(shè),選成都創(chuàng)新互聯(lián)公司。
求和
awk -F : -v sum=0 '{sum+=$3} END{print sum}' /etc/passwd
或者
awk -F : '{sum+=$3} END{print sum}' /etc/passwd
默認(rèn)變量為0
規(guī)定日志格式
$17為domainname
$19為request
$21為響應(yīng)狀態(tài)碼
應(yīng)用1: 匹配統(tǒng)計(jì)F5日志中,含有某個(gè)域名的數(shù)量
可以按照以下方法來套
[root@CentOS-6-121 scripts]# awk -F: '$1=="root" {print $0}' /etc/passwd | wc -l 1
對(duì)以上進(jìn)行改版,因?yàn)榻y(tǒng)計(jì)的時(shí)候利用了wc -l 進(jìn)行了,現(xiàn)在不需要wc -l ,awk完成統(tǒng)計(jì)
[root@CentOS-6-121 scripts]# awk -F: -v n=0 '{if($1=="root") n++;} END{print n}' /etc/passwd 1
-v 可以指定變量,在 awk ''中利用變量的時(shí)候直接使用,不需要"$n" 這個(gè)地方要區(qū)別shell
注意: 以下語句,默認(rèn)不指定n變量的時(shí)候,雖然可以出結(jié)果,是因?yàn)樵趎++的時(shí)候會(huì)默認(rèn)設(shè)置n為0,但是這樣會(huì)出現(xiàn)bug,當(dāng)沒有匹配的時(shí)候,去大于n的時(shí)候就不是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]#
應(yīng)用2: 使用shell中的變量和定義多變量 和邏輯運(yùn)算符
&& 邏輯與
|| 邏輯或
! 否
~ 匹配字符串 !~ 不匹配后面更正則表達(dá)式
-v key1=value1 -v key2-values
引用變量?jī)煞N方式
1
name="John"
-v myname=$name '{print myname}'
2 在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
測(cè)試語句:
與
[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 中正規(guī)的寫法)
注意:
判斷匹配的方法:
1)$n~正則表達(dá)式
2)if($n~正則表示式) print $
如果你的awk中使用了 BEGIN語句,就一定要使用 if 不能使用模式匹配,否則報(bào)錯(cuò)
如:
報(bào)錯(cuò):
[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
應(yīng)用3: awk中的數(shù)組
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
應(yīng)用四:統(tǒng)計(jì)目錄下的一部分目錄的數(shù)據(jù)大小
du -s stu* | awk '{sum=sum+$1} END{print sum}'
數(shù)據(jù)庫(kù)的連接情況
netstat -tanp |awk '/3306/ {print $5}' |awk -F ":" '{a[$1]++}END{for (i in a) print a[i],i}' |sort -nr
應(yīng)用五:行范圍指定
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
實(shí)例:
awk -F: 'NR==2,NR==5 {print $1}' /etc/passwd
awk -F: 'NR>1 && NR<6{print $1}' /etc/passwd
案例6: 打印awk第一次匹配到的關(guān)鍵字,之后的所有行!
分兩步,第一找出第一次匹配的行,匹配nobody賬號(hào)
awk -F ":" '{if($1 ~ "nobody") print NR;}' passwd
15
25
思考,如何只匹配到一次后,就退出awk繼續(xù)向下匹配而直接退出查找。
改良:
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
為什么要做一個(gè)a!=0 的條件,因?yàn)闆]有匹配到nobody的時(shí)候,未定義賦值過的變量再awk中默認(rèn)值為0。
案例七: awk中調(diào)用系統(tǒng)命令
awk -F ":" '{if($1== "nobody") {system("echo this is noboy user")}} ' passwd
或者: $1=="root" 字符串一定要用引號(hào)引起來,不然在awk里面就是變量拉
awk -F ":" '$1=="root" {system("echo this is noboy user")} ' /etc/passwd
案例7: awk多分隔符切,分隔符為[
rabbitmq的集群狀態(tài) partitions行 {partitions,[]}] 如果[] 中有內(nèi)容i表示集群不正常。
if [ "x" != "x$(sudo /usr/sbin/rabbitmqctl cluster_status |grep partitions |awk -F '[\\[\\]]' '{print $2}')" ];then echo 0;else echo 1;fi
案例8: 統(tǒng)計(jì)nf(iptables 跟蹤鏈表中 各協(xié)議的數(shù)量)
awk '{a[$3]++ } END{for (k in a) print k,a[k]}' /proc/net/nf_conntrack
tcp 11
udp 26
icmp 1
案例7. 使用split內(nèi)置函數(shù)進(jìn)行分割
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 是默認(rèn)變量,或者使用grep實(shí)現(xiàn)
grep -H root /etc/passwd
#-H 是顯示文件名在匹配的行前面
內(nèi)置函數(shù)的使用
split的用法:
一、split 初始化和類型強(qiáng)制
awk的內(nèi)建函數(shù)split允許你把一個(gè)字符串分隔為單詞并存儲(chǔ)在數(shù)組中。你可以自己定義域分隔符或者使用現(xiàn)在FS(域分隔符)的值。
格式:
split (string, array, field separator)
split (string, array) -->如果第三個(gè)參數(shù)沒有提供,awk就默認(rèn)使用當(dāng)前FS值。
例2:計(jì)算指定范圍內(nèi)的和(計(jì)算每個(gè)人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的函數(shù)
替換正則表達(dá)式的內(nèi)容
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: 正則表達(dá)式
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()函數(shù)
length([s])
返回字符串的長(zhǎng)度,如果s沒有提供,默認(rèn)是$0。
[root@cuizhiliang ~]# cat /etc/issue |awk '{print length($2)}'
7
2
0
#分析文本中每行的字符大小 找到很長(zhǎng)的那一行
[root@cuizhiliang ~]# cat /etc/issue |awk '{print length()}'
26
18
0
4 文本處理 大小寫轉(zhuǎn)換函數(shù) toupper(string), tolower(string)
awk -F: 'NR==1,NR==2{print toupper($NF)}' /etc/passwd
/BIN/BASH
/SBIN/NOLOGIN
5 index函數(shù)
index(s, t)
返回t中的字符串出現(xiàn)在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 調(diào)用系統(tǒng)命令 重要的是調(diào)用系統(tǒng)給的命令的時(shí)候 參數(shù)適用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 -n|awk '/^[1-9]/{system("arp -d "$1)}' |