Awk这件上古神兵你会用了吗
source link: http://mp.weixin.qq.com/s?__biz=MzUzMzE4MDY0Nw%3D%3D&%3Bmid=2247483893&%3Bidx=1&%3Bsn=85f6a2063048cc244aedde3172444e32
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
花括号MC(huakuohao-mc):关注JAVA基础编程及大数据,注重经验分享及个人成长。
AWK
诞生于1977的贝尔实验室,是由 Alfred Aho,Peter Weinberger和Brian Kernighan三位大神开发, AWK
的命名是由三位作者的Family Name的首字母组成。
三位大神开发 AWK
的初衷是为了方便快速的处理文本及数据信息,在当年那个即没有 python
也没有 go
的年代,这是一个很酷也很有意义的事情;不过话说回来,即便是现在有了 Python
跟 Go
, AWK
在日常线上运维方面仍然占据一席之地,而且几乎不可替代。
如果你对 AWK
还是不甚了解,那么希望通过这篇博文,能够让各位做个简单入门,如果这篇文章还能提起你学习 AWK
的兴趣就更好了。
AWK
的程序一般都很短,但并不是说 AWK
写不出逻辑复杂的程序。 AWK
像你学过的其它语言一样,支持变量自定义,数组结构, for
循环等等,同时也支持自定义函数。
假设我们打算处理一个在线商店的后台日志,内容如下:
1python基础教程 山治 34.50 5 2python高级教程 索隆 40.00 6 3python实战 娜美 38 3 4java编程思想 弗兰克 48.00 6 5Vue教程 javascript小组 55.00 8 6awk基础教程 路飞 42 3
第一列为书名,第二列为作者,第三列为价格,第四列为当日销售数量。我们将该文件命名为 awk_books.log
。接下来我们将通过一些实际的案例需求来学习 AWK
找出价格大于40的书籍
1awk '$3>40 {print $0}' awk_books.log
输出:
1$ awk '$3>40 {print $0}' awk_books.log 2java编程思想 弗兰克 48.00 6 3Vue教程 javascript小组 55.00 8 4awk基础教程 路飞 42 3
解释
awk
的意思是告诉操作系统我要执行
awk
程序,请做好准备。单引号里面的内容为具体的程序逻辑。
awk_books.log
为要处理的文件。
写 awk
的程序其实很简单,因为是有固定套路的。套路就是 'pattern {action}'
, pattern
称为模式, action
称为动作。
awk
会自动读入要处理文件的每一行内容,依次用 pattern
去匹配,如果匹配成功,则执行 action
。对于上面的例子, pattern
为 $3>40
, action
为 {print $0}
。
注意: pattern
跟 action
不必同时存在,后面我会有例子给大家解释什么意思。
到此为止,对于上面的小例子,除了 $3
和 $0
你还不理解以外,其它应该都了解了。
awk
会将输入的每一行按照空白字符进行分隔,因此分隔之后的第一列就是 $1
,第二列就是 $2
,以此类推,我们的例子中书价在第三列,自然就是 $3
,变量 $0
则代表整行记录。
如果要处理的文本内容不是按照空白字符分隔怎么办?你可以这样处理。
1echo "hello-world" | awk 'BEGIN{FS="-"} {print $1}'
输出的结果都为 hello
FS
为 awk
的内置变量,表示输入列的分隔符,默认为空白符。上面的例子中我们将 FS
的默认值设置成我们希望的样子,也就是 -
。除了 FS
以外,跟分隔符相关的内置变量还有输出列分隔符 OFS
,输入行分隔符 RS
,输出行分隔符 ORS
。我就不一一举例展示了。
BEGIN
表示的意思是 AWK
程序开始执行之前,执行 BEGIN
关键字之后的语句,而且只执行一次,所以经常用来初始化变量或者文件头。除了 BEGIN
,还有 END
,我后面还会有例子介绍,大家不要着急。
好了,这里先做个简单的小结,然后继续出发。
1.我们知道了如何在命令行终端调用
AWK
程序。
2.知道了
AWK
程序的固定套路为
'pattern {action}'
格式
3.了解了内置变量
$0
,
$1
,以及
FS
的作用。
接下来通过一些具体的样例继续学习。
打印出每一行最后一列
1awk '{print $NF}' awk_books.log
输出结果:
1$ awk '{print $NF}' awk_books.log 25 36 43 56 68 73
这个例子中,明显没有 pattern
而只有 action
。 AWK
中如果没有 pattern
,则默认匹配所有行。而 NF
为 AWK
的内置变量,表示每一行有多少列。所以 $NF
自然就代表着最后一列的输出内容。基于这个例子,你可以尝试着打印出每一行的倒数第二列内容,代码如下:
1awk '{print $(NF-1) }' awk_books.log
只打印出第二行内容
1awk 'NR == 2' awk_books.log
输出结果:
1$ awk 'NR == 2' awk_books.log 2python高级教程 索隆 40.00 6
这个例子明显没有 action
只有 pattern
,如果没有写 action
则执行默认 action
,默认的 action
就是打印匹配的行内容。 NR
也是内置变量,表示 AWK
已经读取的行数。
打印每一行的内容及行号
1awk '{print NR,$0}' awk_books.log
输出结果:
1$ awk '{print NR,$0}' awk_books.log 21 python基础教程 山治 34.50 5 32 python高级教程 索隆 40.00 6 43 python实战 娜美 38 3 54 java编程思想 弗兰克 48.00 6 65 Vue教程 javascript小组 55.00 8 76 awk基础教程 路飞 42 3
print
里面用逗号分隔要打印的多个内容,输出的时候逗号会被空格替代。
更好的输出
接上面的例子,我们让输出结果更易读一些。
1awk 'BEGIN{print"编号 书名 作者 价格 销量"; print""} {print NR,$0} END{print"";print "输出结束!"}' awk_books.log
输出结果
1$ awk 'BEGIN{print"编号 书名 作者 价格 销量"; print""} {print NR,$0} END{print"";print "输出结束!"}' awk_books.log 2编号 书名 作者 价格 销量 3 41 python基础教程 山治 34.50 5 52 python高级教程 索隆 40.00 6 63 python实战 娜美 38 3 74 java编程思想 弗兰克 48.00 6 85 Vue教程 javascript小组 55.00 8 96 awk基础教程 路飞 42 3 10 11输出结束!
BEGIN
,在前面已经提到了过了,这里是为了加深一下大家的理解。 BEGIN
和 END
后面跟随的语句都只执行一次,即在程序的开头和结束。
打印包含Java的行
1awk '/java/ {print $0}' awk_books.log
输出结果:
1$ awk '/java/ {print $0}' awk_books.log 2java编程思想 弗兰克 48.00 6 3Vue教程 javascript小组 55.00 8
这个样例的匹配模式是个正则表达式,只要有匹配的内容就会输出对应的行。你可以根据业务需求写出更复杂的正则表达式。
打印第一列包含java的行
1awk '$1 ~/java/ {print $0}' awk_books.log
输出结果:
1$ awk '$1 ~/java/ {print $0}' awk_books.log 2java编程思想 弗兰克 48.00 6
打印第一列不包含Java的行
1awk '$1 !~/java/ {print $0}' awk_books.log
输出结果:
1$ awk '$1 !~/java/ {print $0}' awk_books.log 2python基础教程 山治 34.50 5 3python高级教程 索隆 40.00 6 4python实战 娜美 38 3 5Vue教程 javascript小组 55.00 8 6awk基础教程 路飞 42 3
统计输入文本的总行数
1awk 'END {print NR}' awk_books.log
输出结果:
1$ awk 'END {print NR}' awk_books.log 26
输出字符数超过33的行
1awk 'length($0)> 33' awk_books.log
输出结果:
1$ awk 'length($0)> 33' awk_books.log 2java编程思想 弗兰克 48.00 6 3Vue教程 javascript小组 55.00 8
length
为内置函数,此外还有很多内置函数,不在此一一列举了,感兴趣的可以去查。
输出价格最高的行
1awk '$3>max {max = $3; maxline=$0} END {print max,maxline}' awk_books.log
输出结果:
1$ awk '$3>max {max = $3; maxline=$0} END {print max,maxline}' awk_books.log 255.00 Vue教程 javascript小组 55.00 8
这里 max
及 maxline
为自定义变量, AWK
里面的变量不用事先声明,直接用就OK,默认值为空或者0。
计算当天销售总价并输出
1awk '{total += $3*$4} END { print total}' awk_books.log
输出结果:
1$ awk '{total += $3*$4} END { print total}' awk_books.log 21380.5
找出所有Python的书目,然后按照价格排序
1awk '$1 ~/python/ {print $0}' awk_books.log|sort -n -k 3 -t ' '
输出结果:
1$ awk '$1 ~/python/ {print $0}' awk_books.log|sort -n -k 3 -t ' ' 2python基础教程 山治 34.50 5 3python实战 娜美 38 3 4python高级教程 索隆 40.00 6
找出所有Python的书目,按照价格排序,并输出价格最高的两条
1awk '$1 ~/python/ {print $0}' awk_books.log|sort -r -n -k 3 -t ' '|head -n 2
输出结果:
1$ awk '$1 ~/python/ {print $0}' awk_books.log|sort -r -n -k 3 -t ' '|head -n 2 2python高级教程 索隆 40.00 6 3python实战 娜美 38 3
最后两个列子借助了 sort
和 head
,不了解两个指令的可以去查一下,这里不做过多的介绍了。
好了,以上这些 AWK
知识应该够各位应付日常的工作需求了。如果还不够怎么办呢?去买两本书,继续深入学啊!
·END·
花括号MC
Java·大数据·个人成长
微信号:huakuohao-mc
点一下你会更好看耶
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK