四,awk格式化

  之前的文章举过很多例子,我们也体验到了awk的格式化能力,但是我们的体验并不全面,所以,现在,我们来更加深刻的了解一下awk的格式化能力,在前文的举例中,我们在使用awk时,通常使用print 对文本进行输出,但是动作print 只能实现简单的文本输出功能,并不能对文本格式进行改变,如果想要改变文本的格式,则需要awk中的另一个动作,此动作与print很像,它就是printf,没错,看到printf,你肯定会想到printf命令,或者想到了C语言中的printf()函数,如果你想到了这些,那么使用printf对你来说应该不在话下了,如果你并没有接触过printf命令或者printf()函数,没有关系,你可以先阅读如下连接对应的文章,即可学会printf命令的使用方法

  printf命令详解

  利用awk中的printf动作,即可对文本进行格式化输出,printf动作的用法与printf命令的用法非常相似,只是有略微的不同而已,不过,我们还是从最简单的示例开始看起,首先对比一下print动作与printf动作的区别,示例如下

[root@node1 ~]# awk '{print $1}' test1
abc
8ua
[root@node1 ~]# awk '{printf $1}' test1
abc8ua[root@node1 ~]# 

   注意:使用print输出时如果不加参数例如本次的$1则默认是输出所有即$0 

      使用printf必须加类似参数$1否则报错

awk '{printf}' test1
awk: cmd. line:1: (FILENAME=test1 FNR=1) fatal: printf: no arguments

   聪明如你一定想到了,既然printf动作的用法与printf命令一样,那么,printf动作有没有printf命令中所谓的"格式替换符"呢?

  必须有啊,"格式替换符"是什么我们就不再赘述了,因为在printf命令详解中已经详细的解释过它,那么我们来使用"格式替换符"来指定一下$1的格式,示例如下。

[root@node1 ~]# awk '{printf "%s\n",$1}' test1
abc
8ua

   如果只看上图中红线标注的部分,你肯定会认为,这就是printf命令的用法,只是printf动作与printf命令在语法上唯一的不同点就是,在使用printf动作时,指定的"格式"与列($1)之间需要用"逗号"隔开,而使用printf命令时,指定的格式与传入的文本不需要使用"逗号"隔开

[root@node1 ~]# awk '{printf "%s\n",$1}' test1
abc
8ua
[root@node1 ~]# printf "%s\n" testString
testString
[root@node1 ~]# 

   其实,它们还有一些其他的不同之处,我们在使用printf命令时,当指定的格式中只有一个"格式替换符",但是传入了多个参数时,那么这多个参数可以重复的使用这一个格式替换符,示例如下

[root@node1 ~]# printf "%s\n" 1 2 3 4 5
1
2
3
4
5

   但是在awk中,我们则不能这样使用,在awk中,格式替换符的数量必须与传入的参数的数量相同,换句话说,格式替换符必须与需要格式化的参数一一对应,示例如下

[root@node1 ~]# awk 'BEGIN{printf "%s\n", 1,2,3,4,5}' 
1
[root@node1 ~]# awk 'BEGIN{printf "%s\n%s\n%s\n%s\n%s\n", 1,2,3,4,5}' 
1
2
3
4
5

   好了,这就是awk中printf动作在使用时的一些注意点。

  我们来总结一下,在awk中使用printf动作时,需要注意以下3点。

  1)使用printf动作输出的文本不会换行,如果需要换行,可以在对应的"格式替换符"后加入"\n"进行转义。

  2)使用printf动作时,"指定的格式" 与 "被格式化的文本" 之间,需要用"逗号"隔开。

  3)使用printf动作时,"格式"中的"格式替换符"必须与 "被格式化的文本" 一一对应。

  

  我们可以利用格式替换符对文本中的每一列进行格式化,示例如下。

[root@node1 ~]# awk '{printf "第一列:%s 第二列:%s\n",$1,$2}' test1
第一列:abc 第二列:123
第一列:8ua 第二列:456

   我们可以利用awk的内置变量FS,指定输入字段分隔符,然后再利用printf动作,进行格式化,示例如下。

[root@node1 ~]# cat test
abc#123#iuy#ddd
8ua#456#auv#ppp#7y7
[root@node1 ~]# awk -v FS="#" '{printf "第一列:%s\t 第二列:%s\n",$1,$2}' test
第一列:abc	 第二列:123
第一列:8ua	 第二列:456

   上例完美的体现了awk的格式化能力,因为awk本身负责文本切割,printf动作负责格式化文本,双剑合璧了。

  继续扩展一下,可以利用awk的begin模式,结合printf动作,输出一个像样的表格,下图中用到的"修饰符"此处不再赘述,如果不明白,参考printf命令详解

[root@node1 ~]# awk -v FS=":" 'BEGIN{printf "%-10s\t %s\n","用户名称","用户ID"} {printf "%-10s\t %s\n",$1,$3}' /etc/passwd
用户名称      	 用户ID
root      	 0
bin       	 1
daemon    	 2
adm       	 3
lp        	 4
sync      	 5
shutdown  	 6
halt      	 7
mail      	 8
operator  	 11
games     	 12
ftp       	 14
nobody    	 99
systemd-network	 192
dbus      	 81
polkitd   	 999
sshd      	 74
postfix   	 89
chrony    	 998
zabbix    	 997
rpc       	 32
rpcuser   	 29
nfsnobody 	 65534
ntp       	 38
libstoragemgmt	 996
ceph      	 167
apache    	 48
jack      	 1000
owen      	 1001
tss       	 59
liuym     	 1002
tcpdump   	 72

   其实话说回来,只要能够灵活的使用printf命令,再结合printf动作使用时的3个注意点,即可快速灵活的掌控它,好了,关于awk的格式化能力,就暂时总结到这里。

posted @ 2020-09-16 17:34  minseo  阅读(383)  评论(0编辑  收藏  举报