注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

朝程序员的博客

与朋友交流计算机网络知识

 
 
 

日志

 
 

awk 命令  

2017-01-17 17:34:37|  分类: Linux |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |


awk
       awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。
       简单来说awk就是把文件逐行的读入,以空格或TAB为默认分隔符将每行切片,切开的部分再进行各种分析处理。

awk脚本基本结构

awk 'BEGIN{ print "start" } pattern{ action } END{ print "end" }' file

一个awk脚本通常由:BEGIN语句块能够使用模式匹配的通用语句块END语句块3部分组成, 这三个部分是可选的。任意一个部分都可以不出现在脚本中,脚本通常是被单引号双引号 例如: awk 'BEGIN{ i=0 } { i++ } END{ print i }' filename awk "BEGIN{ i=0 } { i++ } END{ print i }" filename

 BEGIN句块在awk开始从输入流中读取行之前被执行,这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中。

END语句块在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是一个可选语句块。

 pattern语句块中的通用命令是最重要的部分,它也是可选的。在pattern{ action } 
pattern可以为定值、计算表达式、awk命令。最终结果为1则执行action、为0则不执行
如果没有pattern语句块,则默认执行{ action }awk读取的每一行都会执行该语句块。
如果没有action,则action默认为{print $0}

awk的工作原理
  • 第一步:执行BEGIN{ commands }语句块中的语句;
  • 第二步:从文件或标准输入(stdin)读取一行,然后执行pattern{ action }语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。
  • 第三步:当读至输入流末尾时,执行END{ commands }语句块。


特殊要点:
$0           表示整个当前行
$1           每行第一个字段
NF          字段数量变量
NR           每行的记录号,多文件记录递增
FNR         与NR类似,不过多文件记录不递增,每个文件都从1开始
\t            制表符
\n           换行符
FS          BEGIN时定义分隔符
RS        输入的记录分隔符, 默认为换行符(即文本是按一行一行输入)
~            匹配,与==相比不是精确比较
!~           不匹配,不精确比较
==         等于,必须全部相等,精确比较
!=           不等于,精确比较
&&      逻辑与
||      逻辑或
+            匹配时表示1个或1个以上
/[0-9][0-9]+/   两个或两个以上数字
/[0-9][0-9]*/    一个或一个以上数字
FILENAME 文件名
OFS      输出字段分隔符, 默认也是空格,可以改为制表符等
ORS        输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕
-F'[:#/]'   定义三个分隔符 print & $0 print 是awk打印指定内容的主要命令 awk '{print}'  /etc/passwd   ==   awk '{print $0}'  /etc/passwd   //全部输出 awk '{print " "}'  /etc/passwd          //不输出passwd的内容,而是输出相同个数的空行, //进一步解释了awk是一行一行处理文本 awk '{print "a"}'    /etc/passwd        //输出相同个数的a行,一行只有一个a字母 awk '{ print $2,$3 }' filename //打印每行的第二和第三个字段

print的参数是以逗号进行分隔时,打印时则以空格或TAB作为定界符

awk '{print $NF}'


-F指定分隔符 awk -F":" '{print $1}'  /etc/passwd  awk -F: '{print $1; print $2}'    /etc/passwd          //将每一行的前二个字段,分行输出,进一步理解一行一行处理文本 awk  -F: '{print $1,$3,$6}' OFS="\t" /etc/passwd        //输出字段1,3,6,以制表符作为分隔符

执行流程 cat /etc/passwd |awk -F ':' 'BEGIN {print "start"} {print $1","$7} END {print "end"}'

start root /bin/bash bin /sbin/nologin daemon /sbin/nologin adm /sbin/nologin lp /sbin/nologin ……
end

awk内置变量

awk有许多内置变量用来设置环境信息,这些变量可以被改变,下面给出了最常用的一些变量。

复制代码
ARGC               命令行参数个数
ARGV               命令行参数排列
ENVIRON            支持队列中系统环境变量的使用
FILENAME           awk浏览的文件名
FNR                浏览文件的记录数
FS                 设置输入域分隔符,等价于命令行 -F选项
NF                 浏览记录的域的个数
NR                 已读的记录数
OFS                输出域分隔符
ORS                输出记录分隔符
RS                 控制记录分隔符

 awk -F ':' '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd

filename:/etc/passwd,linenumber:1,columns:7,linecontent:root:x:0:0:root:/root:/bin/bash


awk编程

 变量和赋值

除了awk的内置变量,awk还可以自定义变量。

下面统计/etc/passwd的账户人数

awk '{count++;print $0;} END{print "user count is ", count}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
......
user count is  40

count是自定义变量。之前的action{}里都是只有一个print,其实print只是一个语句,而action{}可以有多个语句,以;号隔开。

 

这里没有初始化count,虽然默认是0,但是妥当的做法还是初始化为0:

awk 'BEGIN {count=0;print "[start]user count is ", count} {count=count+1;print $0;} END{print "[end]user count is ", count}' /etc/passwd
[start]user count is  0
root:x:0:0:root:/root:/bin/bash
...
[end]user count is  40

条件语句

 awk中的条件语句是从C语言中借鉴来的,见如下声明方式:

复制代码
if (expression) {
    statement;
    statement;
    ... ...
}

if (expression) {
    statement;
} else {
    statement2;
}

if (expression) {
    statement1;
} else if (expression1) {
    statement2;
} else {
    statement3;
}



循环语句

awk中的循环语句同样借鉴于C语言,支持while、do/while、for、break、continue,这些关键字的语义和C语言中的语义完全相同。

显示/etc/passwd的账户
这里使用for循环遍历数组

复制代码
awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd
0 root
1 daemon
2 bin
3 sys
4 sync
5 games
......
复制代码


  评论这张
 
阅读(3)| 评论(0)

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018