GNU awk的輸出格式化和操作符

printf命令

  • 格式化輸出:printf “FORMAT”, item1, item2, …

(1) 必須指定FORMAT

(2) 不會自動換行,需要顯式給出換行控制符,\n

(3) FORMAT中需要分別為后面每個item指定格式符

  • 格式符:與item一一對應

%c: 顯示字符的ASCII碼

%d, %i: 顯示十進制整數

%e, %E:顯示科學計數法數值

%f:顯示為浮點數

%g, %G:以科學計數法或浮點形式顯示數值

%s:顯示字符串

%u:無符號整數

%%: 顯示%自身

  • 修飾符:

#[.#]:第一個數字控制顯示的寬度;第二個#表示小數點后精度,%3.1f

-: 左對齊(默認右對齊)

%-15s ?+:顯示數值的正負符號 %+d

%3.1f表示一共3個字符,小數點占一位,1表示小數點之后占一位,整數也只能占一位了

 

printf支持格式化輸出,按照定義的格式,把對應的字符打印出來。格式定義了將來要打印的列的顯示格式

 

printf示例

awk -F: ‘{printf “%s”,$1}’ /etc/passwd 表示把$1按照字符串格式顯示出來

awk -F: ‘{printf “%s\n”,$1}’ /etc/passwd 表示把$1按照字符串格式顯示出來,并且換行

awk -F: ‘{printf “%-20s %10d\n”,$1,$3}’ /etc/passwd

awk -F: ‘{printf “Username: %s\n”,$1}’ ?/etc/passwd

awk -F: ‘{printf “Username: %s,UID:%d\n”,$1,$3}’ ?/etc/passwd

awk -F: ‘{printf “Username: %15s,UID:%d\n”,$1,$3}’ ??/etc/passwd

awk -F: ‘{printf “Username: %-15s,UID:%d\n”,$1,$3}’ ??/etc/passwd

 

 

[root@localhost ~]# awk -F: ‘{printf “%s”,$1}’ /etc/passwd

rootbindaemonadmlpsyncshutdownhaltmailoperatorgamesftpnobodysystemd-networkdbuspolkitdabrtlibstoragemgmtrpccolordsaslauthrtkitpulsechronyrpcusernfsnobodyntptssusbmuxdgeoclueqemuradvdsetroubleshootsssdgdmgnome-initial-setupsshdavahipostfixtcpdumpding[root@localhost ~]#

 

[root@localhost ~]# awk -F: ‘{printf “%s?“,$1}’ /etc/passwd

root bin daemon adm lp sync shutdown halt mail operator games ftp nobody systemd-network dbus polkitd abrt libstoragemgmt rpc colord saslauth rtkit pulse chrony rpcuser nfsnobody ntp tss usbmuxd geoclue qemu radvd setroubleshoot sssd gdm gnome-initial-setup sshd avahi postfix tcpdump ding [root@localhost ~]#

 

 

[root@localhost ~]# awk -F: ‘{printf “%s\n“,$1}’ /etc/passwd

root

bin

daemon

adm

lp

sync

 

加顯示寬度

awk -F: ‘{printf “%s:%d\n“,$1,$3}’ /etc/passwd

%s:%d\n要顯示的格式

$1,$3要顯示的數據

放在雙引號中的純粹是格式,例如

[root@localhost ~]# awk -F: ‘{printf “username:%s : uid%d\n”,$1,$3}’ /etc/passwd

username:root : uid0

username:bin : uid1

username:daemon : uid2

username:adm : uid3

username:%s : uid%d\n只是顯示格式

 

給定顯示寬度,默認右對齊

[root@localhost ~]# awk -F: ‘{printf “%30s %30d\n”,$1,$3}’ /etc/passwd

root ?????????????????????????????0

bin ?????????????????????????????1

daemon ?????????????????????????????2

adm ?????????????????????????????3

lp ?????????????????????????????4

sync ?????????????????????????????5

shutdown ?????????????????????????????6

指定顯示左對齊和不指定顯示的有對齊

[root@localhost ~]# awk -F: ‘{printf “%30s %15d\n”,$1,$3}’ /etc/passwd

root ????????????????????????????????????????0

bin ?????????????????????????????????????????1

daemon ??????????????????????????????????????2

adm ?????????????????????????????????????????3

lp ??????????????????????????????????????????4

sync ????????????????????????????????????????5

shutdown ????????????????????????????????????6

halt ????????????????????????????????????????7

mail ????????????????????????????????????????8

operator ???????????????????????????????????11

 

打印變量,文件有多少行就打印多少遍

[root@localhost ~]# awk -F: -v n=123.45678 ‘{printf “%8.4f\n”,n}’ /etc/passwd

123.4568

 

加BEGIN進行打印控制,小數點之后定義的是3位,多出的位數進行四舍五入,因為總共8個字符,不夠的就補空格

[root@localhost ~]# awk -F: -v n=123.45678 ‘BEGIN{printf “%8.3f\n”,n}’

123.457

 

 

 

 

 

 

操作符

  • 算術操作符:

x+y, x-y, x*y, x/y, x^y, x%y

-x: 轉換為負數

+x: 轉換為數值

  • 字符串操作符:沒有符號的操作符,字符串連接
  • 賦值操作符:

=, +=, -=, *=, /=, %=, ^=

++, —

  • 下面兩語句有何不同

awk ?‘BEGIN{i=0;print ++i,i}’

awk ?‘BEGIN{i=0;print i++,i}’

 

[root@localhost ~]# awk ?‘BEGIN{i=0;print ++i,i}’

1 1

[root@localhost ~]# awk ?‘BEGIN{i=0;print i++,i}’

0 1

 

取模運算。加BEGIN就不需要等著輸入內容了,默認需要根據文件內容或者標準輸入做處理

[root@localhost ~]# awk -v m=10 -v n=3 ‘BEGIN{print m%n}’

1

[root@localhost ~]# awk -v m=10 -v n=3 ‘BEGIN{print m+=n}’

13

[root@localhost ~]# awk -v m=10 -v n=3 ‘BEGIN{print m+=n,m}’

13 13

[root@localhost ~]# awk -v m=10 -v n=3 ‘BEGIN{print m+=n,m++}’

13 13

[root@localhost ~]# awk -v m=10 -v n=3 ‘BEGIN{print m+=n,m++,m}’

13 13 14

[root@localhost ~]# awk -v m=10 -v n=3 ‘BEGIN{print m+=n,++m,m}’

13 14 14

[root@localhost ~]# i=10;let j=i++; echo $j

10

[root@localhost ~]# i=10;let j=++i; echo $j

11

 

 

操作符

  • 比較操作符:

==, !=, >, >=, <, <=

  • 模式匹配符:

~:左邊是否和右邊匹配包含

!~:是否不匹配

  • 示例:

awk –F: ‘$0 ~ /root/{print $1}‘ ?/etc/passwd

awk ‘$0~“^root”‘ /etc/passwd

awk ?‘$0 ?!~ /root/‘ ??/etc/passwd

awk ?–F: ‘$3==0’ ?/etc/passwd

 

[root@localhost ~]# awk -F: ‘$0 ~ /root/{print $1}’ ?/etc/passwd

root

operator

顯示以ding開頭的行,不寫{}表示顯示整行,這個例子相當于省略了{print $0}

[root@localhost ~]# awk ‘$0~”^ding”‘ /etc/passwd

ding:x:1000:1000:ding:/home/ding:/bin/bash

 

[root@localhost ~]# awk ‘$0 ~ “^ding”‘ /etc/passwd

ding:x:1000:1000:ding:/home/ding:/bin/bash

 

 

不是ding開頭的其他的行

[root@localhost ~]# awk ‘$0 !~?“^ding”‘ /etc/passwd

root:x:0:0:root:/root:/bin/bash

…………

 

兩個斜線之間表示正則表達式,和雙引號效果一致

[root@localhost ~]# awk ‘$0 ~ /^ding/’ /etc/passwd

ding:x:1000:1000:ding:/home/ding:/bin/bash

[root@localhost ~]# awk ‘$0 !~ /^ding/’ /etc/passwd

root:x:0:0:root:/root:/bin/bash

 

使用的是擴展的正則表達式

[root@localhost ~]# awk ‘$0 ~ /^(ding|root|f)/’ /etc/passwd

root:x:0:0:root:/root:/bin/bash

ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

ding:x:1000:1000:ding:/home/ding:/bin/bash

使用引號效果一致

[root@localhost ~]# awk ‘$0 ~ “^(ding|root|f)”‘ /etc/passwd

root:x:0:0:root:/root:/bin/bash

ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

ding:x:1000:1000:ding:/home/ding:/bin/bash

 

打印出第三列等于0的行

[root@localhost ~]# awk -F: ‘$3==0’ /etc/passwd

root:x:0:0:root:/root:/bin/bash

 

打印第三列大于1000的行

[root@localhost ~]# awk -F: ‘$3>=1000’ /etc/passwd

nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin

ding:x:1000:1000:ding:/home/ding:/bin/bash

 

相當于省略了{print $0}

[root@localhost ~]# awk -F: ‘$3>=1000{print $0}‘ /etc/passwd

nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin

ding:x:1000:1000:ding:/home/ding:/bin/bash

$3>=1000實際上就是??program:pattern{action statements;..}中的pattern,相當于一個條件。如果符合條件,就打印內容,沒讀入一行就判斷條件是否成立,如果為真,就打印整行,想當于省略了{print $0}

 

如果是個變量沒有定義將會被認定為假

[root@localhost ~]# awk -F: ‘i’ /etc/passwd

 

i有值就為真,打印整行的內容

[root@localhost ~]# awk -F: -v i=””?‘i’ /etc/passwd i=空字符串

[root@localhost ~]# awk -F: -v i=”?” ‘i’ /etc/passwd i=空格

root:x:0:0:root:/root:/bin/bash

bin:x:1:1:bin:/bin:/sbin/nologin

 

變量的值為假:0 未定義 ?空都是假,只要有值就為真

 

awk -F: -v i=100 ‘i’ /etc/issue 相當于 awk -F: -v i=100 ‘i{print $0}’ /etc/issue

 

只要不是0 未定義 空 ??都是真

[root@localhost ~]# awk -F: -v i=-100 ‘i{print $0}’ /etc/issue

\S

Kernel \r on an \m

 

 

操作符

  • 邏輯操作符:與&&,或||,非!
  • 示例:

awk –F: ‘$3>=0 && $3<=1000 {print $1}’ /etc/passwd

awk -F: ‘$3==0 || $3>=1000 {print $1}’ /etc/passwd

awk -F: ‘!($3==0) {print $1}’ /etc/passwd

awk -F: ‘!($3>=500) {print $3}’ /etc/passwd

  • 函數調用: function_name(argu1, argu2, …)
  • 條件表達式(三目表達式): ?selector?if-true-expression:if-false-expression

示例:

awk -F: ‘{$3>=1000?usertype=”Common User”:usertype=”Sysadmin or SysUser”;printf “%15s:%-s\n”,$1,usertype}’ /etc/passwd

 

默認打印出多有符合條件的行

[root@localhost ~]# awk -F: ‘$3>0 && $3<1000’ /etc/passwd

bin:x:1:1:bin:/bin:/sbin/nologin

daemon:x:2:2:daemon:/sbin:/sbin/nologin

 

只打印一部分數據

[root@localhost ~]# awk -F: ‘$3>0 && $3<1000{print $1,$3}’ /etc/passwd

bin 1

daemon 2

 

精確查詢使用shell類型是bash結尾的行

[root@localhost ~]# awk -F: ‘$NF == “/bin/bash” {print $1,$NF}’ /etc/passwd

root /bin/bash

ding /bin/bash

 

模糊查詢使用shell類型是bash結尾的行

[root@localhost ~]# awk -F: ‘$NF ~ “bash$” {print $1,$NF}’ /etc/passwd

root /bin/bash

ding /bin/bash

 

 

打印文件的所有內容

i的值不為空,條件表現為真,所以每讀取一行就打印一行

[root@localhost ~]# awk -v i=10 ‘i’ /etc/issue

\S

Kernel \r on an \m

 

取反條件為假,不打印任何內容

[root@localhost ~]# awk -v i=10 ‘!i‘ /etc/fstab

 

[root@localhost ~]# awk ‘{i=10; print i}’ /etc/issue

10

10

[root@localhost ~]# awk ‘{i=10; print !i}’ /etc/issue

0

0

 

有值取反就為假

[root@localhost ~]# awk ‘{i=0;print !i++,i}’ /etc/issue

1 1

1 1

 

括號不起作用

[root@localhost ~]# awk ‘{i=0;print !(i++),i}’ /etc/issue

1 1

1 1

[root@localhost ~]# awk ‘{i=2;print !(i++),i}’ /etc/issue

0 3

0 3

[root@localhost ~]# awk ‘{i=2;print !i++,i}’ /etc/issue

0 3

0 3

[root@localhost ~]# awk ‘{i=-1;print !i++,i}’ /etc/issue

0 0

0 0

先取反,打印出來,最后++

 

[root@localhost ~]# awk ‘{i=-1;print !++i,i}’ /etc/issue

1 0 1:0取反為1。-1 ++ 后的值為0,0取反的值為1

1 0 0:-1++后的值為0

[root@localhost ~]# awk ‘{i=0;print !++i,i}’ /etc/issue

0 1

0 1

先++,再取反

 

例如:awk ‘{i=0;print !++i,i}’

++i之后的值為1,取反為0

i的值為:++i=1

 

{i=-1;print !++i,i}:++在前,就先做++(++i),做完之后在打?。╬rint !++i)

{i=-1;print !i++,i}++在后,先做別的事(print !i),最后在++(i++)

 

 

判斷用戶的ID是否大于1000,大于1000是普賬號,低于1000是系統賬號

[root@localhost ~]# awk -F: ‘{$3>=1000?usertype=”common user”:usertype=”sysuser”;printf “%-15s: %-30s %8d \n”,usertype,$1,$3}’ /etc/passwd

sysuser ???????: root ?????????????????????????????????0

sysuser ???????: bin ??????????????????????????????????1

sysuser ???????: daemon ???????????????????????????????2

sysuser ???????: adm ??????????????????????????????????3

sysuser ???????: lp ???????????????????????????????????4

sysuser ???????: sync ?????????????????????????????????5

common user ???: ding ??????????????????????????????1000

本文來自投稿,不代表Linux運維部落立場,如若轉載,請注明出處:http://www.www58058.com/90686

(0)
無言勝千言無言勝千言
上一篇 2018-01-01 15:36
下一篇 2018-01-01 15:47

相關推薦

欧美性久久久久