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日志中,含有某個域名的數量
可以按照以下方法來套
<code>[root@CentOS-6-121 scripts]</code><code># awk -F: '$1=="root" {print $0}' /etc/passwd | wc -l</code>
<code>1</code>
對以上進行改版,因為統計的時候利用了wc -l 進行了,現在不需要wc -l ,awk完成統計
<code>[root@CentOS-6-121 scripts]</code><code># awk -F: -v n=0 '{if($1=="root") n++;} END{print n}' /etc/passwd </code>
-v 可以指定變量,在 awk ''中利用變量的時候直接使用,不需要"$n" 這個地方要差別shell
注意: 以下語句,預設不指定n變量的時候,雖然可以出結果,是因為在n++的時候會預設設定n為0,但是這樣會出現bug,當沒有比對的時候,去大于n的時候就不是0而是空
<code>[root@CentOS-6-121 scripts]</code><code># awk -F: '{if($1=="root") n++;} END{print n}' /etc/passwd </code>
bug:
<code>[root@CentOS-6-121 scripts]</code><code># awk -F: '{if($1=="rooot") n++;} END{print n}' /etc/passwd </code>
<code>[root@CentOS-6-121 scripts]</code><code>#</code>
應用2: 使用shell中的變量和定義多變量 和邏輯運算符
&& 邏輯與
|| 邏輯或
! 否
~ 比對字元串 !~ 不比對後面更正規表達式
-v key1=value1 -v key2-values
引用變量兩種方式
1
name="John"
-v myname=$name '{print myname}'
2 在awk中我們可以通過“’$變量名’”的方式讀取sell scrpit程式中的變量。
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
測試語句:
與
<code>[root@CentOS-6-121 scripts]</code><code># awk -F: '$1=="root" && $3==0 {print $0}' /etc/passwd</code>
<code>root:x:0:0:root:</code><code>/root</code><code>:</code><code>/bin/bash</code>
或
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 不能使用模式比對,否則報錯
如:
報錯:
<code>[root@CentOS-6-121 scripts]</code><code># awk -F: '$1=="root" && $3==0 BEGIN{n=0} {n++} END{print n}' /etc/passwd</code>
awk: $1=="root" && $3==0 BEGIN{n=0} {t++} END{print t}
awk: ^ syntax error
改為:
<code>[root@CentOS-6-121 scripts]</code><code># awk -F: 'BEGIN{n=0} {if($1 =="root" && $3==0)n++} END{print n}' /etc/passwd</code>
<code>使用變量:</code>
<code>[root@master ~]</code><code># n=1000</code>
<code>[root@master ~]</code><code># awk -v n=$n -F: '$3==n {print $1" "$3}' /etc/passwd</code>
<code>elasticsearch 1000</code>
應用3: awk中的數組
<code>awk</code> <code>-F : </code><code>'{bash_array[$NF]++} END {for(i in bash_array) {print i,bash_array[i]}}'</code> <code>/etc/passwd</code>
/bin/nologin 1
/sbin/shutdown 1
/bin/false 1
/bin/bash 11
/sbin/nologin 28
/sbin/halt 1
/bin/sync 1
3 指定域名的
<code>[root@shnh-bak001 f5-log]$ </code><code>awk</code> <code>'$17 ==</code><code>"gold.dianpingfang.com"</code> <code>{++domain[$21]} END {</code><code>for</code><code>(k</code>
<code>in</code> <code>domain) print k,domain[k]}' access.log</code>
2
200 4498
301 2
500 15
302 321
304 2
應用四:統計目錄下的一部分目錄的資料大小
<code>du</code> <code>-s stu* | </code><code>awk</code> <code>'{sum=sum+$1} END{print sum}'</code>
資料庫的連接配接情況
<code>netstat</code> <code>-tanp |</code><code>awk</code> <code>'/3306/ {print $5}'</code> <code>|</code><code>awk</code> <code>-F </code><code>":"</code> <code>'{a[$1]++}END{for (i in a) print a[i],i}'</code> <code>|</code><code>sort</code> <code>-nr</code>
應用五:行範圍指定
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賬号
<code>awk</code> <code>-F </code><code>":"</code> <code>'{if($1 ~ "nobody") print NR;}'</code> <code>passwd</code>
15
25
思考,如何隻比對到一次後,就退出awk繼續向下比對而直接退出查找。
改良:
<code>awk</code> <code>-F </code><code>":"</code> <code>'{if($1== "nobody") {print NR; exit 0}}'</code> <code>passwd</code>
第二: 列印第15行之後的所有行
<code>awk</code> <code>-F </code><code>":"</code> <code>'{if(NR > 15) print $0;}'</code> <code>passwd</code>
或者(以下行範圍更适用)
awk -F: 'NR>15{print $1}' /etc/passwd
可以提高難道綜合成一條awk語句
<code>awk</code> <code>-F </code><code>":"</code> <code>'{if($1== "nobody") {a=NR}} {if(NR>a && a!=0) print $0}'</code> <code>passwd</code>
為什麼要做一個a!=0 的條件,因為沒有比對到nobody的時候,未定義指派過的變量再awk中預設值為0。
案例七: awk中調用系統指令
<code>awk</code> <code>-F </code><code>":"</code> <code>'{if($1== "nobody") {system("echo this is noboy user")}} '</code> <code>passwd</code>
或者: $1=="root" 字元串一定要用引号引起來,不然在awk裡面就是變量拉
awk -F ":" '$1=="root" {system("echo this is noboy user")} ' /etc/passwd
案例7: awk多分隔符切,分隔符為[
rabbitmq的叢集狀态 partitions行 {partitions,[]}] 如果[] 中有内容i表示叢集不正常。
<code>if</code> <code>[ </code><code>"x"</code> <code>!= </code><code>"x$(sudo /usr/sbin/rabbitmqctl cluster_status |grep partitions |awk -F '[\\[\\]]' '{print $2}')"</code> <code>];</code><code>then</code> <code>echo</code> <code>0;</code><code>else</code> <code>echo</code> <code>1;</code><code>fi</code>
案例8: 統計nf(iptables 跟蹤連結清單中 各協定的數量)
<code>awk</code> <code>'{a[$3]++ } END{for (k in a) print k,a[k]}'</code> <code>/proc/net/nf_conntrack</code>
tcp 11
udp 26
icmp 1
案例7. 使用split内置函數進行分割
<code>tac haproxy.log | </code><code>awk</code> <code>'{</code>
<code> </code><code>split</code><code>($6,a,</code><code>":"</code><code>)</code>
<code> </code><code>if</code><code>(a[1]~</code><code>"05/Mar/2017"</code><code>){ </code>
<code> </code><code>print $0</code>
<code> </code><code>}</code>
<code> </code><code>if</code><code>(a[1]~</code><code>"04/Mar/2017"</code><code>){</code><code>exit</code><code>}</code>
<code> </code><code>}' >> .</code><code>/a_access</code><code>.log </code>
<code>exit</code>
案例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月份的工資之和)
<code>[root</code><code>@test</code> <code>~]</code><code># cat test.txt</code>
<code>Tom </code><code>2012</code><code>-</code><code>12</code><code>-</code><code>11</code> <code>car </code><code>53000</code>
<code>John </code><code>2013</code><code>-</code><code>01</code><code>-</code><code>13</code> <code>bike </code><code>41000</code>
<code>vivi </code><code>2013</code><code>-</code><code>01</code><code>-</code><code>18</code> <code>car </code><code>42800</code>
<code>Tom </code><code>2013</code><code>-</code><code>01</code><code>-</code><code>20</code> <code>car </code><code>32500</code>
<code>John </code><code>2013</code><code>-</code><code>01</code><code>-</code><code>28</code> <code>bike </code><code>63500</code>
<code>[root</code><code>@test</code> <code>~]</code><code># awk '{split($2,a,"-");if(a[2]==01){b[$1]+=$4}}END{for(i in b)print i,b[i]}' test.txt </code>
<code>vivi </code><code>2800</code>
<code>Tom2500</code>
<code>John4500</code>
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
#分析文本中每行的字元大小 找到很長的那一行
[root@cuizhiliang ~]# cat /etc/issue |awk '{print length()}'
26
18
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)}'
本文轉自殘劍部落格51CTO部落格,原文連結http://blog.51cto.com/cuidehua/1771599如需轉載請自行聯系原作者
cuizhiliang