像sed一样,awk是UNIX重要的工具,目前有三个版本:
AWK - the (very old) original from AT&T
NAWK - A newer, improved version from AT&T
GAWK - The Free Software foundation’s version
通常情况下,awk还是使用最为普遍的。
一、为什么要学习awk
awk是很优秀的过滤器和报告编写器,能够很方便的处理文本文件,尤其是其能够特异性的针对行、列进行文本处理,这使得awk比其他传统的语言都要方便。你可以把它看成是伪C语言,它和C语言有很多相似的地方。使用它能够对字符串处理,包括搜索、过滤、编辑、控制输出等。尤其是配和其他的shell命令及管道命令,是的文本处理异常方便。如果你用R或者Python处理文本,你要写一个脚本,导入各种包和模块,然后读入文件,然后再按照自己需求一步一步处理,而在awk中,可能你仅仅需要一行命令即可。
另外,awk本身的含义并不是笨拙的意思(awkward),它实际上是其开发者名字的首字母缩写。
二、基本结构
awk语言的基本组织形式是:
pattern {action}
其中pattern用于说明何时执行action。和很多其他unix工具一样,awk也是按行来执行的。pattern用来检验读入的每一行是否符合条件,如果是,该行则在action中被处理。默认条件下,pattern是能够匹配每一行,也就是所有行都会在action中进行处理。
此外,还有经常用到的两个关键字“BEGIN”和“END”。“BEGIN”用来说明在开始读入行之前的行为,“END”用来说明处理完所有行之后的行为。
BEGIN { print “START” }
pattern { action }
END { print “STOP” }
例子:$ls -ltrh能够列出当前文件路径下所有的文件信息,如下,
total 2008 drwx------+ 3 Yiguan staff 102B 4 Nov 2016 Movies drwx------ 3 Yiguan staff 102B 4 Nov 2016 Applications drwxr-xr-x 31 Yiguan staff 1.0K 28 Dec 2016 vcftools drwxr-xr-x 4 Yiguan staff 136B 16 Jan 2017 bin -rw-r--r-- 1 Yiguan staff 268B 16 Jan 2017 whamm.log drwx------@ 7 Yiguan staff 238B 17 Jan 2017 plink_mac drwxr-xr-x 12 Yiguan staff 408B 17 Jan 2017 hapbin drwxr-xr-x 5 Yiguan staff 170B 17 Jan 2017 miniconda2 -rw-r--r-- 1 Yiguan staff 1.0K 18 Jan 2017 plink.log drwxr-xr-x@ 28 Yiguan staff 952B 18 Jan 2017 selectionTools-master drwxr-xr-x 4 Yiguan staff 136B 20 Mar 2017 perl5 drwxr-xr-x 159 Yiguan staff 5.3K 13 Jun 2017 blastdb drwx------+ 4 Yiguan staff 136B 26 Jun 2017 Music drwxr-xr-x+ 6 Yiguan staff 204B 15 Aug 2017 Public drwxr-xr-x 3 Yiguan staff 102B 22 Aug 2017 ncbi drwx------+ 6 Yiguan staff 204B 6 Oct 2017 Pictures drwxr-xr-x 164 Yiguan staff 5.4K 12 Mar 10:34 b2gWorkspace drwxr-xr-x 7 Yiguan staff 238B 12 Mar 10:36 b2gFiles drwx------@ 74 Yiguan staff 2.5K 5 Apr 11:54 Library -rw-r--r-- 1 Yiguan staff 993K 20 Apr 12:36 rodeo.log drwx------+ 42 Yiguan staff 1.4K 8 Jun 16:56 Documents drwx------+ 77 Yiguan staff 2.6K 12 Jun 12:38 Desktop drwx------+ 183 Yiguan staff 6.1K 12 Jun 13:39 Downloads drwx------@ 36 Yiguan staff 1.2K 13 Jun 15:59 Dropbox
那么如果我只想要文件名和文件大小,该怎么处理呢?$ls -ltrh | awk 'BEGIN{print "FILE\tSIZE"} NR>1 {print $9,"\t",$5} END{print "--END--"}'
只需要这一行就可以输出:
FILE SIZE Movies 102B Applications 102B vcftools 1.0K bin 136B whamm.log 268B plink_mac 238B hapbin 408B miniconda2 170B plink.log 1.0K selectionTools-master 952B perl5 136B blastdb 5.3K Music 136B Public 204B ncbi 102B Pictures 204B b2gWorkspace 5.4K b2gFiles 238B Library 2.5K rodeo.log 993K Documents 1.4K Desktop 2.6K Downloads 6.1K Dropbox 1.2K --END--
其中,"ls -ltrh"不做过多解释,就是按时间逆序列出所有文件的详细信息;“|”就是管道操作符, 即将前面的标准输出作为下一个命令的标准输入;后面就进入awk命令,整个命令用单引号,其中“NR>1"实际pattern,来判断后面action,即“{print $9,"\t",$5}”是否执行。“NR”指行数,“NR>1"代表从第二行开始执行action。在执行之前,还有“BEGIN”命令用于先行输出”FILE\tSIZE",其中\t表示制表符;另外$9和$5分别代表一行中第9个和第5个参数(和Linux一样),在这儿你可以理解为每一行的第9列和第5列。
需要指出的是awk能够识别双引号中的"\t",但是不能够识别双引号中的“$9",这一点和Linux不同。所以你如果写成
{print “$9\t$5”}
就会出现错误的输出!
当然,你也可以把它写成脚本。保存成awk_example.sh,然后
$chmod a+x awk_example.sh $ls -ltrh | ./awk_example.sh
通过这一部分,我们可以初步了解awk的语法结构。后面会有更多详细用法。
====== THE END =====
参考资料:http://www.grymoire.com/Unix/Awk.html