; GNU awk的输出格式化和操作符 | Linux运维部落

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),做完之后在打印(print !++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.178linux.com/90686

发表评论

电子邮件地址不会被公开。 必填项已用*标注

联系我们

400-080-6560

在线咨询:点击这里给我发消息

邮件:1660809109@qq.com

工作时间:周一至周五,9:30-18:30,节假日同时也值班