shark AWK 练习

原文链接 https://www.jianshu.com/p/3f771928670c

AWK

$ cat gy.txt
机构号  机构名称        省别    尾箱号  尾箱状态   领用柜员号   领用柜员姓名    币种    余额
11007eee        北京东城区街支行   北京    03      未领用           156     19001.68
11007fff        北京东城区街支行   北京    03      未领用           840     2672.00
11007aaa        北京东城区街支行   北京    04      未领用           156     7261.31
11007ccc        北京朝阳区路支行   北京    02      未领用           156     161490.08
110088ee        北京朝阳区路支行   北京    03      未领用           840     19711.00
34009eff         山西煤矿区路支行   山西    03      未领用           156     282370.23
11007eee        山西煤矿区路支行   山西    03      未领用           156     282370.23
11007eee        山西煤矿区路支行   山西    03      未领用           156     282370.23
11007264        山东平阴县支行     山东    02      未领用          156     304516.23
11007889        山东济阳县支行   北京    04      未领用           840     24551.00
11007264        北京朝阳区支行     北京    02      未领用           156     304516.23
11007284        北京朝阳区支行     北京    02      领用     1002  巫妖王           156     304516.23
11007194        北京朝阳区行       北京    02      未领用           156     304516.23
11007264        河南中原区支行     河南    02      未领用          156     304516.23

过滤记录
过滤条件为:

 awk '$3=="河南" && $5 == "未领用" {print $6,$7}' qf.txt

其中的 == 为比较运算符。其他比较运算符:!=, >, <, >=, <=

各种过滤记录的方式:

$ awk ' $4 > 3 {print $0}' gy.txt

如果我们需要表头的话,我们可以引入内置变量NR:

$ awk '$3=="山东" && $5=="未领用"  || NR==1 ' gy.txt

再加上格式化输出:

$ awk '$3=="山东" && $5=="未领用" || NR==1 {printf "%-10s %-21s %-6s\n",$1,$2,$3}' gy.txt

字符串匹配

示例:

查找 平阴县支行的所有信息

awk '$2  ~  /平阴县/ || NR==1 {print NR, $1,$4}' gy.txt

~ 表示模式开始。
/ / 中是模式。这就是一个正则表达式的匹配。

其实awk可以像grep一样,进行逐行匹配,就像这样:

$ awk '/.*县/' gy.txt

我们可以使用 “/平阴县|济阳县/” 来匹配 平阴县 或者 济阳县 :

$ awk '$2 ~ /平阴县|济阳县/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" gy.txt

再来看看模式取反的例子:

$ awk '$2 !~ /平阴县/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" gy.txt

或是:

$ awk '!/平阴县/' gy.txt

折分文件

awk拆分文件很简单,使用重定向就好了。

下面这个例子,是按第 3 例分隔文件,相当的简单(其中的NR!=1表示不处理表头)。

$ awk 'NR!=1{print > $3}' gy.txt
$ ls
gy.txt  北京     山东     山西     山东  河南

你也可以把指定的列输出到文件:

awk 'NR!=1{print $2,$4,$5 > $3}' gy.txt

再复杂一点:(注意其中的if-else-if语句,可见awk其实是个脚本解释器)

$ awk 'NR!=1 {if($3 ~ /北京|山东/) print > "1.txt";
else if($3 ~ /山西/) print > "2.txt";
else print > "3.txt" }' gy.txt
 
$ ls ?.txt
1.txt  2.txt  3.txt

统计

下面的命令计算所有的 txt 文件的文件大小总和。

$ ls -l  *.txt | awk '{sum+=$5} END {print sum}'
2511401

我们再来看一个统计各个各省份网点数量的用法:

$ awk 'NR!=1 {a[$3]++;} END {for (i in a) print i ", " a[i];}' gy.txt
北京, 69
山西, 20
江苏, 10
山东, 16

a 是数组名称
[$3] 是数组的索引号,这个索引号可以是普通字符
ifor 循环 数组 得到的 索引号
a[i] 是获取到索引对应的值

再来看看统计每个用户的进程的占了多少内存(注:sum的RSS那一列)

$ ps aux | awk 'NR!=1 {a[$1]+=$6;} END { for(i in a) print i ", " a[i]"KB";}'

awk脚本

BEGINEND,这两个关键字意味着执行前和执行后的意思,语法如下:

BEGIN { 这里面放的是执行前的语句 }

END {这里面放的是处理完所有的行后要执行的语句 }

{这里面放的是处理每一行时要执行的语句}

示例:

假设有这么一个文件(学生成绩表):

$ cat score.txt
Marry   2143 78 84 77
Jack    2321 66 78 45
Tom     2122 48 77 71
Mike    2537 87 97 95
Bob     2415 40 57 62

我们的awk脚本如下:

$ cat cal.awk
#!/bin/awk -f
#处理每行之前
BEGIN {
    math = 0
    english = 0
    computer = 0
 
    printf "NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL\n"
    printf "---------------------------------------------\n"
}

#处理中
{
    math+=$3
    english+=$4
    computer+=$5
    printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5
}

#处理后
END {
    printf "---------------------------------------------\n"
    printf "  TOTAL:%10d %8d %8d \n", math, english, computer
    printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR
}

我们来看一下执行结果:(也可以这样运行 ./cal.awk score.txt)

$ awk -f cal.awk score.txt
NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL
---------------------------------------------
Marry  2143     78       84       77      239
Jack   2321     66       78       45      189
Tom    2122     48       77       71      196
Mike   2537     87       97       95      279
Bob    2415     40       57       62      159
---------------------------------------------
  TOTAL:       319      393      350
AVERAGE:     63.80    78.60    70.00

环境变量

怎么和环境变量交互:(使用-v参数和ENVIRON,使用ENVIRON的环境变量需要export)

$ x=5
$ y=10
$ export y
 
$ echo $x $y
5 10
 
$ awk -v val=$x '{print $1, $2, $3, $4+val, $5+ENVIRON["y"]}' OFS="\t" score.txt
Marry   2143    78      89      87
Jack    2321    66      83      55
Tom     2122    48      82      81
Mike    2537    87      102     105
Bob     2415    40      62      72

最后,我们再来看几个小例子:

#从file文件中找出长度大于80的行
awk 'length>80' file
 
#按连接数查看客户端IP
netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr
 
#打印99乘法表
seq 9 | sed 'H;g' | awk -v RS='' '{for(i=1;i<=NF;i++)printf("%dx%d=%d%s", i, NR, i*NR, i==NR?"\n":"\t")}'

关于其中的一些知识点可以参看gawk的手册:

内建变量,参看:http://www.gnu.org/software/gawk/manual/gawk.html#Built_002din-Variables

流控方面,参看:http://www.gnu.org/software/gawk/manual/gawk.html#Statements

内建函数,参看:http://www.gnu.org/software/gawk/manual/gawk.html#Built_002din

正则表达式,参看:http://www.gnu.org/software/gawk/manual/gawk.html#Regexp

"""

# 访问TOP 20 的IP
16348 58.16.183.52
awk  '$9==200 {print $1}'  2018-05-10-0000-2330_app.log | sort |uniq -c |sort -r |head -20


访问状态码为20X的  TOP 10的IP
2097 125.70.184.99
2000 183.225.69.158
awk  '$9 > 200 && $9 < 300{print $1}' 2018-05-10-0000-2330_app.log  | sort |uniq -c |sort -r |head


访问TOP 20 的url
250563 http://app.xxx.com/update/2018-04-04/dangbeimarket_4.0.9_162_znds.apk
awk  '$9 == 200{print $7,$9}' 2018-05-10-0000-2330_app.log | sort |uniq -c |sort -r |head -20

访问状态码为20X的  TOP 10的url
248786 http://app.znds.com/update/2018-04-04/dangbeimarket_4.0.9_162_znds.apk
awk  '$9 > 200 && $9 < 300{print $7,$9}' 2018-05-10-0000-2330_app.log | sort |uniq -c |sort -r |head


访问次数超过1W的IP
58.16.184.247
58.16.183.52
awk  '{print $1}' 2018-05-10-0000-2330_app.log| sort |uniq -c |sort -r |awk '$1 > 10000 {print $1}'


访问状态码为404的  TOP 10的url
1017 http://app.xxx.com/update/fixedaddress/kuaisou_qcast.apk.md5
awk  '$9 == 404 {print $1}' 2018-05-10-0000-2330_app.log | sort |uniq -c |sort -r |head
"""
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,542评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,822评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,912评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,449评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,500评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,370评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,193评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,074评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,505评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,722评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,841评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,569评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,168评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,783评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,918评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,962评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,781评论 2 354

推荐阅读更多精彩内容

  • 转载:https://coolshell.cn/articles/9070.html?utm_source=cof...
    一梦三四年lyp阅读 249评论 0 0
  • 转载 原文的排版和内容都更加友好,并且详细,我只是在这里贴出了一部分留作自己以后参考和学习,如希望更详细了解AWK...
    XKirk阅读 3,214评论 2 25
  • 一. AWK 说明 awk的处理文本和数据的方式:它逐行扫描文件,从第一行到最后一行,寻找匹配的特定模式的行,并...
    西华子阅读 933评论 0 4
  • awk简介 awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入、一个或多...
    yeahuh阅读 3,963评论 0 7
  • AWK awk 是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入、一个或多个...
    花泽菠菜xqc阅读 315评论 0 1