使用awk重新编排字段
awk非常擅长处理结构化数据和生成表单.和sed和grep很相似.由于awk具备各种及哦啊本语言的特点,所以可以把它看做是一种脚本语言.
先来看个案例,只查看/etc/passwd/目录下的用户名和组名
awk -F: ‘{print $1,$5}’ /etc/passwd
意思是:使用:来分割这一行,把这一行的第一和第五个字段打印出来.
调用awk:
第一种方式:
awk [-F 分隔符] ‘commands’ input-file(s)
这里的commands是真正的awk命令,[-F 分隔符]适可选的,awk默认使用空格分隔,因此如果要浏览域间有空格的文本,不必指定这个选项,但如果浏览如passwd文件,此文件各域使用冒号作为分隔符,则必须使用-F选项: awk -F : 'commands' input-file
第二种方式:
将所有awk命令插入一个文件,并使awk程序可执行,然后用awk命令解释器作为脚本的首行,以便通过键入脚本名称来调用它
第三种方式
将所有awk命令插入一个单独文件,然后调用,如: awk -f awk-script-file input-file
-f选项指明在文件awk-script-file的awk脚本,input-file是使用awk进行浏览的文件名
任何awk语句都是由模式和动作组成,在一个awk脚本中可能有许多语句。模式部分决定动作语句何时触发及触发事件。动作即对数据进行的操作,如果省去模式部分,动作将时刻保持执行状态
模式可以是任何条件语句或复合语句或正则表达式,模式包含两个特殊字段BEGIN和END,使用BEGIN语句设置计数和打印头,BEGIN语句使用在任何文本浏览动作之前,之后文本浏览动作依据输入文件开始执行;END语句用来在awk完成文本浏览动作后打印输出文本总数和结尾状态标志,有动作必须使用{}括起来
实际动作在大括号{}内指明,常用来做打印动作,但是还有更长的代码如if和循环looping语句及循环退出等,如果不指明采取什么动作,awk默认打印出所有浏览出的记录
awk执行时,其浏览标记为$1,$2...$n,这种方法称为域标记。使用$1,$3表示参照第1和第3域,注意这里使用逗号分隔域,使用$0表示使用所有域。例
awk -F :‘{print $0}’ /etc/passwd //表示打印所有域并把结果重定向到/etc/passwd中(所谓的域就是某一行中的字段)
awk -F : ‘{print $0}’ /etc/passwd ///在屏幕上显示出来
awk ‘{print $1,$4}’ /etc/passwd //只打印第一和第四域(第一和第四字段)
awk -F: ‘BRGIN{print ”hahaha\n---”}{print $1 “\t” $4}’ /etc/passwd //表示打印头信息,在输入的内容的第一行前加上”hahaha”,同时内容之间用tab键分开.
awk -F: 'BEGIN{print "hahaha\n---"}{print $1 "\t" $4}END{print "end\n"}' /etc/passwd //这个代表的意思是说打印开头结尾
awk的条件匹配符
<、<=、==、!=、>=、~匹配正则表达式、!~不匹配正则表达式
匹配:awk -F: '{if($1~/root/)print $0}' /etc/passwd //在/etc/passwd这个文件中,如果某条记录的第一个字段含有root就打印整条记录到屏幕上,注意,只要包含就行.
精确匹配 : awk -F: '$1=="root"{print $0}' /etc/passwd //某行中的第一个字段必须等于root才打印.
不匹配 : awk -F: '$0!~"root"{print $0}' /etc/passwd 打印整条不包含root的记录,使用双引号或者反斜杠都是一样的.
其他的操作符具体不在介绍.
awk的设计目的就是操作记录与字段:awk读取输入记录(通常是一些行),然后自动将各个记录且分为字段.awk将每条记录内的字段树木,存储到内建变量NF.
通过上面的例子,差不多已经总体上有了一定得了解:
awk ‘{print $NF}’ 打印最后一行
比较特殊的字段是编号0,表示整条记录.
awk内置变量
ARGC 命令行参数个数
ARGV 命令行参数排列
ENVIRON 支持队列中系统环境变量的使用
FILENAME awk浏览的文件名
FNR 浏览文件的记录数
FS 设置输入域分隔符,等价于命令行 -F选项
NF 浏览记录的域的个数
NR 已读的记录数
OFS 输出域分隔符
ORS 输出记录分隔符
RS 控制记录分隔符
案例:
统计/etc/passwd:文件名,每行的行号,每行的列数,对应的完整行内容:
awk -F ':' '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd
除了awk的内置变量,awk还可以自定义变量.
例如:统计/etc/passwd的行数:
awk '{count++}END{print count}' /etc/passwd
count是自定义变量,这里没有初始化count,虽然默认是0,但是妥当的做法还是初始化为0.
awk 'BEGIN{count=0}{count=count+1}END{print count}' /etc/passwd
例如:统计某个文件夹下的文件占用的字节数
ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size}'
如果按照M为单位显示
ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size/1024/1024,"M"}'
小结:
如果需要从输入的数据文件夹中取出特定的文本行,主要的工具为grep程序.
sed是处理简单字符串替换的主要工具.大部分shell脚本在使用sed时几乎都是用来做替换的操作.
“从最左边开始,扩展至最长”这个法则描述了匹配的文本在何处匹配以及匹配扩展到多长.在使用sed,awk或其他交互式文本编辑程序时,这个法则相当重要.
cut命令用以剪下选定的字符范围或字段,join则是用来结合记录中具有共同键值的字段的文件.
awk多半用于简单的”单命令行程序”,当你想要只显示选定的字段,或是重新安排行内的字段顺序时,就是awk排上用场的时候了.由于awk还是编程语言,即使在尖端的程序里,他也能发挥强大的作用.