1. 程式人生 > 實用技巧 >四,awk格式化

四,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的格式化能力,就暫時總結到這裡。