天天看點

awk使用小結

<code>awk</code><code>博大精深,本文僅持續更新在工作中頻繁使用的方法。</code>

<code>【AWK】</code>

<code>使用邏輯判斷 </code><code>if</code> <code>else</code>

<code>在邏輯處理過程中調用外部指令,并使用 getline 得到輸出,最終指派給變量</code>

<code>#!/bin/bash</code>

<code>#</code>

<code># 2017/11/9</code>

<code># decode etcdv3 output k/v with base64</code>

<code>### "key": "foo",</code>

<code>### "value": "bar",</code>

<code>ETCDCTL_API=3 etcdctl get -w json --prefix </code><code>'/'</code> <code>|jq </code><code>'.'</code> <code>|</code><code>awk</code> <code>-F</code><code>'"'</code> <code>'{</code>

<code>    </code><code>if</code> <code>($2==</code><code>"key"</code><code>) {</code>

<code>        </code><code>"base64 -d&lt;&lt;&lt; \""</code><code>$4</code><code>"\""</code> <code>|getline $4</code>

<code>        </code><code>print $1</code><code>"\""</code><code>$2</code><code>"\""</code><code>$3</code><code>"\""</code><code>$4</code><code>"\""</code><code>$5</code>

<code>    </code><code>} </code><code>else</code> <code>if</code> <code>($2==</code><code>"value"</code><code>) {</code>

<code>        </code><code>"base64 -d&lt;&lt;&lt; \""</code><code>$4</code><code>"\""</code> <code>|getline s_decode</code>

<code>        </code><code>if</code> <code>(index(s_decode, </code><code>"{"</code><code>) != 0) {</code>

<code>            </code><code>print $1</code><code>"\""</code><code>$2</code><code>"\""</code><code>$3s_decode$5</code>

<code>        </code><code>} </code><code>else</code> <code>{</code>

<code>            </code><code>print $0</code>

<code>        </code><code>}</code>

<code>    </code><code>} </code><code>else</code> <code>{</code>

<code>        </code><code>print $0</code>

<code>    </code><code>}</code>

<code>}'</code>

<code>在處理資料前,先指派幾個變量</code>

<code>awk</code> <code>-</code><code>v</code> <code>dt_a=`</code><code>date</code> <code>+%s` -</code><code>v</code> <code>dt_b=`</code><code>date</code> <code>+%s` </code><code>'BEGIN{if(dt_a==dt_b) {print 1} else {print 0}}'</code>

<code>截取一行資料中指定的2個數字做加減乘除運算:</code>

<code>請仔細對比下述3種方式的差異</code>

<code>[root@tvm01 asset]</code><code># echo 'aaa 1%, bbb 2%, ccc 3%, ddd 4%' |sed -r 's/.*([0-9]).*([0-9]).*([0-9]).*([0-9]).*/\1+\2/' |bc</code>

<code>3</code>

<code>[root@tvm01 asset]</code><code># echo 'aaa 1%, bbb 2%, ccc 3%, ddd 4%' |awk -F'%,' '{print $1$2}' |sed 's/[a-z]//g' |awk '{print $1+$2}'</code>

<code>[root@tvm01 asset]</code><code># echo 'aaa 1%, bbb 2%, ccc 3%, ddd 4%' |awk -F'[ %,]' '{print $2+$6}'                                   </code>

<code>去掉空格:</code>

<code>awk</code> <code>'{ result=gensub(/ /,"",1);print result }'</code>

<code>列印某一段内容:</code>

<code>awk</code> <code>'{print $7}'</code> <code>access.log</code>

<code>統計IP數量:</code>

<code>awk</code> <code>'{cs[$1]+=1} END {for(c in cs) print cs[c], c}'</code> <code>access.log |</code><code>sort</code> <code>-nr</code>

<code>列印最後一列:</code>

<code>awk</code> <code>'{print $8 " " $NF} '</code> <code>access.log</code>

<code>統計大小:</code>

<code>awk</code> <code>'{print $10 "  " $1 "  " $7}'</code> <code>access.log|</code><code>awk</code> <code>'{B+=$1} END {print B/1024/1024 " MB"}'</code>

<code>統計TCP狀态:</code>

<code>netstat</code> <code>-n | </code><code>awk</code> <code>'/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'</code>

<code>統計日志中http狀态碼:</code>

<code>zcat 2013-07-15-0000-2330_test.company.com.*|</code><code>awk</code> <code>'{print $9}'</code><code>|</code><code>sort</code><code>|</code><code>uniq</code> <code>-c|</code><code>sort</code> <code>-nr|</code><code>more</code>

<code>統計日志格式最後一行是源站IP的對應資料:</code>

<code>zcat 2013-07-15-*|</code><code>awk</code> <code>'$7~/test.company.com/{print $NF}'</code><code>|</code><code>sort</code><code>|</code><code>uniq</code> <code>-c|</code><code>sort</code> <code>-nr|</code><code>head</code>

<code>統計日志中第2行超過1M大小的URL,并列印第2行的大小和第3行的URL</code>

<code>awk</code> <code>'$2~/.*M/ {print $2"\t"$3}'</code> <code>access.log</code>

<code>統計日志中18點通路</code><code>test</code><code>.company.com,狀态碼為200的資料,列印響應時間和源站位址:</code>

<code>zcat 2013-07-15-18*|</code><code>grep</code> <code>test</code><code>.company.com|</code><code>awk</code> <code>'$9=="200"{print $(NF-7),$NF}'</code><code>|</code><code>sort</code><code>|</code><code>uniq</code> <code>-c|</code><code>sort</code> <code>-nr|</code><code>more</code>

<code>統計延時超過100ms的請求:</code>

<code>zcat 2013-07-15-18*|</code><code>grep</code> <code>test</code><code>.company.com|</code><code>awk</code> <code>'$9=="0"&amp;&amp;$(NF-7)&gt;100 {print $(NF-7)}'</code><code>|</code><code>sort</code><code>|</code><code>uniq</code> <code>-c|</code><code>sort</code> <code>-nr|</code><code>more</code>

<code>NR:整個腳本目前已經讀過的記錄數,就是行号,從1開始。随着所讀檔案的數目,一直累加。</code>

<code>FNR:同NR,不過是相對于目前在讀的檔案記錄數。每開始讀一個檔案時,從1開始累加,相當于行号。讀完一個檔案後就會清0,新的檔案又會從1開始。</code>

<code>http:</code><code>//in</code><code>.sdo.com/?p=1054</code>

<code>統計http code為502的數量,IP</code>

<code>假設有以下檔案:</code>

<code>cs.502 : 統計了出現502的次數和IP,格式為“次數  IP”</code>

<code>cs.502.ip : 從cs.502中篩選出IP,格式為“IP”</code>

<code>cs.502.country : 利用qqwry做IP到地理位置的轉換,格式為“IP  地理位置”</code>

<code>現在的需求是,把cs.502和cs.502.country合并</code>

<code>awk</code> <code>'NR==FNR {a[$2]=$0;next} NR&gt;FNR {print a[$1] " "$2}'</code> <code>cs.502 cs.502.country &gt;cs.502.log</code>

<code>計算http code 海外相對全部的占比是多少</code>

<code>test</code><code>.all 的内容是:</code>

<code>46255 0</code>

<code>967 504</code>

<code>218 502</code>

<code>test</code><code>.oversea 的内容是:</code>

<code>1171 0</code>

<code>408 504</code>

<code>205 502</code>

<code>awk</code> <code>'NR==FNR {a[$2]=$1;next} NR&gt;FNR {printf "%.2f% ", $1/a[$2]*100;print $2}'</code> <code>test</code><code>.all </code><code>test</code><code>.oversea </code>

<code>2.53% 0</code>

<code>42.19% 504</code>

<code>94.04% 502</code>

<code>計算百分比:</code>

<code>echo</code> <code>55 4001638 |</code><code>awk</code> <code>'{printf "%.4f%\n",$1/$2*100}'</code>

<code>根據後3位來排序:</code>

<code>1231234214329049203</code>

<code>4239049230492039402</code>

<code>3209402394023940234</code>

<code>awk</code> <code>'{print $0,substr($0,length($0)-2,3)}'</code> <code>x.txt |</code><code>sort</code> <code>-n -k 2 | </code><code>awk</code> <code>'{print $1}'</code>

<code>sed</code> <code>-r </code><code>'s/(.*)((.){3})/\1|\2/'</code> <code>test</code><code>.txt |</code><code>sort</code> <code>-n -k 2 -t \| |</code><code>sed</code> <code>'s/|//g'</code>

<code>去重 </code>

<code>awk</code> <code>'!a[$1]++'</code> <code>test</code><code>.log</code>

<code>展示</code><code>df</code><code>的簡單版本,隻顯示磁盤分區和對應的used的值:</code>

<code>df</code> <code>-h |</code><code>sed</code> <code>'1d'</code> <code>|</code><code>egrep</code> <code>-</code><code>v</code> <code>""</code><code>/dev/shm</code><code>"|"</code><code>/dev/mapper</code><code>""</code> <code>|</code><code>awk</code> <code>'{print $NF"\t"$(NF-1)}'</code> <code>|</code><code>while</code> <code>read</code> <code>a b; </code><code>do</code> <code>echo</code> <code>"$a used: $b"</code><code>; </code><code>done</code>

<code>統計swap占用的程序:</code>

<code>for</code> <code>i </code><code>in</code> <code>`</code><code>cd</code> <code>/proc</code><code>;</code><code>ls</code> <code>|</code><code>grep</code> <code>"^[0-9]"</code><code>|</code><code>awk</code> <code>' $0 &gt;100'</code><code>` ;</code><code>do</code> <code>awk</code> <code>'/Swap:/{a=a+$2}END{print '</code><code>"$i"</code><code>',a/1024"M"}'</code> <code>/proc/</code><code>$i</code><code>/smaps</code> <code>;</code><code>done</code> <code>|</code><code>sort</code> <code>-k2nr |</code><code>head</code>

<code>統計最小值,使用 BEGIN 來初始化變量,</code><code>if</code><code>做循環判斷,END輸出結果</code>

<code>test</code><code>.log:</code>

<code>96.3738</code>

<code>95.72002499999999</code>

<code>96.78004999999999</code>

<code>95.8748</code>

<code>96.146125</code>

<code>96.7587</code>

<code>96.11826666666666</code>

<code>96.69625</code>

<code>95.88227499999999</code>

<code>96.4341</code>

<code># cat test.log |awk 'BEGIN {min=100} {if ($1&lt;min) {min=$1;x=$1}} END {print x}'</code>

<code>統計伺服器的cpu,記憶體和磁盤資訊,截取小數點,四舍五入</code>

<code>echo</code> <code>`</code><code>hostname</code><code>` |</code><code>cut</code> <code>-d</code><code>'.'</code> <code>-f1 \</code>

<code>&amp;&amp; </code><code>echo</code> <code>`</code><code>cat</code> <code>/proc/cpuinfo</code> <code>|</code><code>grep</code> <code>processor |</code><code>wc</code> <code>-l`</code><code>'C'</code> <code>|</code><code>tr</code> <code>'\n'</code> <code>'|'</code> <code>\</code>

<code>&amp;&amp; </code><code>cat</code> <code>/proc/meminfo</code> <code>|</code><code>grep</code> <code>'MemTotal'</code> <code>|</code><code>awk</code> <code>'{m=$(NF-1)/1024/1024;print m"G"}'</code> <code>|</code><code>tr</code> <code>'\n'</code> <code>'|'</code> <code>\</code>

<code>&amp;&amp; lsblk -o SIZE,TYPE,MOUNTPOINT |</code><code>grep</code> <code>-E </code><code>'(data|disk1)'</code> <code>|</code><code>awk</code> <code>'{print $1}'</code> <code>\</code>

<code>&amp;&amp; </code><code>echo</code> <code>&amp;&amp; lsblk -o SIZE,TYPE,MOUNTPOINT &amp;&amp; </code><code>free</code> <code>-m |</code><code>grep</code> <code>Mem |</code><code>awk</code> <code>'{print "Mem="$2"M"}'</code>

<code>參考</code>

<code>1、Getline </code>

<code>https:</code><code>//www</code><code>.gnu.org</code><code>/software/gawk/manual/html_node/Getline_002fVariable_002fPipe</code><code>.html</code><code>#Getline_002fVariable_002fPipe</code>

本文轉自 pcnk 51CTO部落格,原文連結:http://blog.51cto.com/nosmoking/1659704,如需轉載請自行聯系原作者