天天看点

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,如需转载请自行联系原作者