四,awk格式化
之前的文章舉過很多例子,我們也體驗到了awk的格式化能力,但是我們的體驗並不全面,所以,現在,我們來更加深刻的瞭解一下awk的格式化能力,在前文的舉例中,我們在使用awk時,通常使用print 對文字進行輸出,但是動作print 只能實現簡單的文字輸出功能,並不能對文字格式進行改變,如果想要改變文字的格式,則需要awk中的另一個動作,此動作與print很像,它就是printf,沒錯,看到printf,你肯定會想到printf命令,或者想到了C語言中的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的格式化能力,就暫時總結到這裡。