awk命令简介
awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符
将每行切片,切开的部分再进行各种分析处理。
awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU 版本。有读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表等功能.
awk命令的使用方法
`awk '{pattern + action}' {filenames}`
其中,pattern就是要表示的正则表达式,用斜杠括起来
; 随后紧接着action脚本,如果action有多句则用分号分隔;最后紧接着文件名称.
应用实例
第一: 默认分隔符
默认分隔符
为空格,$0则表示所有域,$1表示第一个域,$n表示第n个域。默认域分隔符
是“空白键” 或 “[tab]键”,所以以下例子中:$1表示登录用户.
[bio@ubuntu ~]$ last -n 5
bio pts/0 :0 Mon Feb 5 12:44 still logged in
bio pts/0 :0 Mon Feb 5 12:10 - 12:44 (00:33)
bio :0 :0 Mon Feb 5 12:02 still logged in
reboot system boot 4.4.0-111-generi Mon Feb 5 12:02 - 14:11 (02:08)
bio pts/9 :0 Mon Feb 5 12:01 - 12:01 (00:00)
wtmp begins Fri Feb 2 12:37:31 2018
[bio@ubuntu ~]$ last -n 5 | awk '{print $1}'bio
bio
bio
reboot
bio
第二: 指定分隔符
使用-F参数指定分隔符
.
[bio@ubuntu ~]$ head /etc/passwd
root:x:0:0:root:/root:/bin/bashdaemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
[bio@ubuntu ~]$ head /etc/passwd|awk -F ":" '{print $1"\t"$7}'
root /bin/bashdaemon /usr/sbin/nologin
bin /usr/sbin/nologin
news /usr/sbin/nologin
第三: BEGIN 和 END
awk工作流程是这样的:先执行BEGING,然后读取文件,读入有/n换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域,随后开始执行模式所对应的动作action
。接着开始读入第二条记录······直到所有的记录都读完,最后执行END操作。
[bio@ubuntu ~]$ head /etc/passwd|awk -F ":" 'BEGIN {print "用户\t目录"} {print $1"\t"$7}'
用户 目录
root /bin/bashdaemon /usr/sbin/nologin
bin /usr/sbin/nologin
第四: awk内置参数
$n 当前记录的第n个字段,字段间由FS分隔。
$0 完整的输入记录。
ARGC 命令行参数的数目。
ARGIND 命令行中当前文件的位置(从0开始算)。
ARGV 包含命令行参数的数组。
CONVFMT 数字转换格式(默认值为%.6g)
ENVIRON 环境变量关联数组。
ERRNO 最后一个系统错误的描述。
FIELDWIDTHS 字段宽度列表(用空格键分隔)。
FILENAME 当前文件名。
FNR 同NR,但相对于当前文件。
FS 字段分隔符(默认是任何空格)。
IGNORECASE 如果为真,则进行忽略大小写的匹配。
NF 当前记录中的字段数。
NR 当前记录数。
OFMT 数字的输出格式(默认值是%.6g)。
OFS 输出字段分隔符(默认值是一个空格)。
ORS 输出记录分隔符(默认值是一个换行符)。
RLENGTH 由match函数所匹配的字符串的长度。
RS 记录分隔符(默认是一个换行符)。
RSTART 由match函数所匹配的字符串的第一个位置。
SUBSEP 数组下标分隔符(默认值是\034)。
[bio@ubuntu ~]$ cat /tmp/awk_test
1 2 3 5
2 3 4 5
3 6 7 9
##NR:第几行;NF:当前行总共几列
[bio@ubuntu ~]$ awk -F '\t' '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /tmp/awk_test
filename:/tmp/awk_test,linenumber:1,columns:4,linecontent:1 2 3 5
filename:/tmp/awk_test,linenumber:2,columns:4,linecontent:2 3 4 5
filename:/tmp/awk_test,linenumber:3,columns:4,linecontent:3 6 7 9
##同样的实现方法
##printf的简便用法
[bio@ubuntu ~]$ awk -F '\t' '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /tmp/awk_test
filename:/tmp/awk_test,linenumber:1,columns:4,linecontent:1 2 3 5
filename:/tmp/awk_test,linenumber:2,columns:4,linecontent:2 3 4 5
filename:/tmp/awk_test,linenumber:3,columns:4,linecontent:3 6 7 9
##输出最后一列##
[bio@ubuntu ~]$ awk -F "\t" '{print $NF}' /tmp/awk_test
5
5
9
##输出偶数行最后一列##
[bio@ubuntu ~]$ awk -F "\t" '{if(NR%2==0) print $NF}' /tmp/awk_test
5
##输出奇数行最后一列##
[ bio@ubuntu ~]$ awk -F "\t" '{if(NR%2==1) print $NF}' /tmp/awk_test
5
9
第五: 正则及循环action
##输出正则匹配的行##
[ bio@ubuntu ~]$ awk '/MI0000001/ {print $0}' /tmp/alias
MI0000001 cel-let-7L;cel-let-7;
##正则匹配的行,以另一格式输出##
##第二列按分号切割成数组,并输出不为空的数组元素##
[bio@ubuntu ~]$ awk '/MI0000001/ {split($2,tmps,";");for(i in tmps){if(tmps[i]){print $1,tmps[i];}}}' /tmp/alias
MI0000001 cel-let-7L
MI0000001 cel-let-7
##同样的结果不同的实现方法##
[bio@ubuntu ~]$ awk '/MI0000001/ {len=split($2,tmps,";");for(i=1;i<len;i++){print $1,tmps[i];}}' /tmp/alias
MI0000001 cel-let-7L
MI0000001 cel-let-7
网友评论