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