zoukankan      html  css  js  c++  java
  • 四,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
    ",$1}' test1
    abc
    8ua
    

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

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

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

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

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

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

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

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

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

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

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

      

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

    [root@node1 ~]# awk '{printf "第一列:%s 第二列:%s
    ",$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	 第二列:%s
    ",$1,$2}' test
    第一列:abc	 第二列:123
    第一列:8ua	 第二列:456
    

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

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

    [root@node1 ~]# awk -v FS=":" 'BEGIN{printf "%-10s	 %s
    ","用户名称","用户ID"} {printf "%-10s	 %s
    ",$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的格式化能力,就暂时总结到这里。

  • 相关阅读:
    BZOJ 1911: [Apio2010]特别行动队
    BZOJ 1096: [ZJOI2007]仓库建设(动态规划+斜率优化)
    BZOJ 2243: [SDOI2011]染色(树链剖分)
    BZOJ 1834: [ZJOI2010]network 网络扩容(网络流+费用流)
    BZOJ 1036: [ZJOI2008]树的统计Count(树链剖分)
    BZOJ 1875: [SDOI2009]HH去散步(矩阵乘法)
    BZOJ 1898: [Zjoi2004]Swamp 沼泽鳄鱼(矩阵乘法)
    BZOJ 2463: [中山市选2009]谁能赢呢?(博弈论)
    BZOJ 2879: [Noi2012]美食节
    BZOJ 1070: [SCOI2007]修车(费用流)
  • 原文地址:https://www.cnblogs.com/minseo/p/13680336.html
Copyright © 2011-2022 走看看