希望各位不要白piao,点个赞或者刷个评论再走,还有【禁止转载】,抄袭转载必究,谢谢合作。
本篇文章主要讲awk,如果已经会了的童鞋,省下时间去了解其他的技术吧~~
----------------------文章概述----------------------
- awk的简单用法以及两个例子
- awk的高级用法
----------------------------------------------------------
【经验分享】工作的程序员经常会用shell或者python3去写一些简单的脚本,或者实现某些简单的数据处理。这是工作中的常态,当然我说的这类程序员是写工程类代码的童鞋,要是算法之类的em……我也没有什么经验,所以这里也不过多的评价。但是为什么要用shell?大家一定有这个疑惑,python3不香么?当然香呀,但是如果一个新的环境原生支持肯定更香呀,然而在shell的数据处理中用的最多的就是sed和awk。如果sed有什么不懂得,看我sed的那篇博文,那篇我写的简直是不能再细了,博文地址:如何用好sed命令?
awk的简单用法以及两个例子
众所周知,sed以行为单位处理文件,awk比sed强的地方在于不仅能以行为单位还能以列为单位处理文件。awk缺省的行分隔符是换行,缺省的列分隔符是连续的空格和Tab,但是行分隔符和列分隔符都可以自定义。(比如awk -F ','
就是按逗号对某个文件进行拆分)比如/etc/passwd文件的每一行有若干个字段,字段之间以:分隔,就可以重新定义awk的列分隔符为:并以列为单位处理这个文件。
awk实际上是一门很复杂的脚本语言,还有像C语言一样的分支和循环结构,但是基本用法和sed类似,awk命令行的基本形式为:
awk option 'script' file1 file2 ...
awk option -f scriptfile file1 file2 ...
和sed一样,awk处理的文件既可以由标准输入重定向得到,也可以当命令行参数传入,编辑命令可以直接当命令行参数传入,也可以用-f参数指定一个脚本文件,编辑命令的格式为:
/pattern/{actions}
condition{actions}
和sed类似,pattern是正则表达式,actions是一系列操作。awk程序一行一行读出待处理文件,如果某一行与pattern匹配,或者满足condition条件,则执行相应的actions,如果一条awk命令只有actions部分,则actions作用于待处理文件的每一行。
【Case1】:文件testfile的内容表示某商店的库存量:
ProductA 30
ProductB 76
ProductC 55
现在要打印每一行的第二列:
awk '{print \$2;}' testfile
运行结果为:
30
76
55
自动变量$1、$2分别表示第一列、第二列等,类似于Shell脚本的位置参数,而$0表示整个当前行。如果位置参数不懂?看我另一篇讲位置参数的博文,什么$@,$1之类的写的十分的详细,博文地址:什么是位置参数?什么是$@?
【Case2】:再比如,如果某种产品的库存量低于75则在行末标注需要订货:
awk '$2<75 {printf "%s\t%s\n", $0, "REORDER";} $2>=75 {print $0;}' testfile
运行结果为:
ProductA 30 REORDER
ProductB 76
ProductC 55 REORDER
可能有小白不理解哈,这东西就相当于一个if……else,学过c的同学应该很明白,%s就是字符串的占位符,这里需要提一下如果没有用到-F那么awk默认是按照空格进行拆分的。剩下的我觉得就没有什么需要说明的,结合运行结果就能一目了然,如果还是有问题评论留言吧。
awk的高级用法
从上面的两个case可见awk也有和C语言非常相似的printf函数。awk命令的condition部分还可以是两个特殊的condition-BEGIN和END,对于每个待处理文件,BEGIN后面的actions在处理整个文件之前执行一次,END后面的actions在整个文件处理完之后执行一次。
awk命令可以像C语言一样使用变量(但不需要定义变量),比如你不需要在使用前搞个 int x= 0;就是不需要声明后再使用,看下面这个例子:
【Case1】:统计一个文件中的空行数
awk '/^ *$/ {x=x+1;} END {print x;}' testfile
可能小白在正则这个地方看不太懂,这个其实很好查,所有语言的正则其实都差不多,这里面的正则就是匹配行的开头和结尾,翻译一下就是匹配每一行。以后我会把我自己整理的各种正则分享出来。如果还是不太懂得baidu一下,baidu不到就google一下。
以上的东西都算比较小case的,就像Shell的环境变量一样,有些awk变量是预定义的有特殊含义的:
内建变量 | 变量含义 |
---|---|
FILENAME | 当前输入文件的文件名,该变量是只读的 |
NR | 当前行的行号,该变量是只读的,R代表record |
NF | 当前行所拥有的列数,该变量是只读的,F代表field |
OFS | 输出格式的列分隔符,缺省是空格 |
FS | 输入文件的列分融符,缺省是连续的空格和Tab |
ORS | 输出格式的行分隔符,缺省是换行符 |
RS | 输入文件的行分隔符,缺省是换行符 |
【Case2】:例如打印系统中的用户帐号列表
awk 'BEGIN {FS=":"} {print $1;}' /etc/passwd
用的比较多的就是NF和NR,这东西就是shell内置的不用声明,直接使用就好了。使用方法跟上面的例子一样,如果还需要我补充一些工作中的一些case,评论留言,因为每个人的水平是不一样的,我也不知道应该写成什么样子,但我还是希望更多崇尚技术的小白能够正确的走这条路,毕竟我在工作之前我就会cd ls这种命令而已 哈哈哈哈