前言

printf命令详解,格式化,awk格式化,printf动作


格式化

printf命令详解

printf命令的作用是按照我们指定的格式输出文本。

  • echo 和printf区别
    输出文本,echo命令也可以进行输出,它们的区别:
[root@node1 ~]# echo testString
testString
[root@node1 ~]# printf testString
testString[root@node1 ~]#

从上述示例中可以看出,在输出文本时,echo命令会对输出的文本进行换行,而printf命令则不会对输出的文本进行换行,使用转义符\n ,示例如下

[root@node1 ~]# printf "testString\n"
testString

printf的优势

在于格式化输出文本,假设,我们有一串文本需要输出,如下

[root@node1 ~]# echo "abc def ghi jkl"
abc def ghi jkl

有一个小需求,将上述文本按照空格分段,每段单独输出在一行

[root@node1 ~]# echo -e "abc \nabc \ndef \nghi \njkl"
abc 
abc 
def 
ghi 
jkl

对于printf,只是通过指定一个固定的"格式",后面的每一段文本都按照指定的格式进行了换行,即使有10000段文本需要换行,也不用担心。

[root@node1 ~]# printf "%s\n" abc def ghi jkl
abc
def
ghi
jkl

printf语法

printf命令的语法如下

printf "指定的格式" "文本1" "文本2" "文本3" ......
[root@node1 ~]# printf "%s\n" abc def ghi jkl

上述语法中的每一个"文本"都会被当做参数项传入printf命令,而每个被传入的参数都会按照指定的"格式"被"格式化"。
4.printf命令详解,格式化,awk格式化,printf动作_开发语言

命令中的"%s\n"即为指定的"格式",而后面的每一段字符串,都被当做参数传入到了printf命令中,并按照我们指定的格式进行了格式化。

“%s"代替了命令的abc,代替了def,代替了ghi,代替了每一个传入的参数,在指定的"格式"中,它代表了每一个传入的参数,当指定格式为”%s\n",当abc被当做参数传入printf命令时,printf就会把"%s\n"中的%s替换成abc,于是,abc就变成了我们指定的格式"abc\n",最终printf输出的就是格式化后的"abc\n",以此类推,每一段文本都被当做一个参数传入printf命令,然后按照指定的格式输出了。

格式替换符

“格式替换符"不只有”%s"一种,"%s"代替了每一个传入的参数,并将他们转化成了"字符串类型","%f"会将每一个传入的参数转换成"浮点类型",如下:

[root@node1 ~]# printf "%s \n" 1 19 18 222
1 
19 
18 
222 
[root@node1 ~]# printf "%f \n" 1 19 18 222
1.000000 
19.000000 
18.000000 
222.000000

分别使用了"%s"替换符和"%f"替换符格式化了相同的内容,但是格式化后的结果却不同。
"%f"自动将传入的数字添加了小数点,将传入的数字参数替换成了浮点数。

可以根据传入参数的不同,使用不同的"格式替换符"去替换。

  • 常用的格式替换符总结如下。
    %s 字符串
    %f 浮点格式(也就是我们概念中的float或者double)
    %b 相对应的参数中包含转义字符时,可以使用此替换符进行替换,对应的转义字符会被转义。
    %c ASCII字符。显示相对应参数的第一个字符
    %d, %i 十进制整数
    %o 不带正负号的八进制值
    %u 不带正负号的十进制值
    %x 不带正负号的十六进制值,使用a至f表示10至15
    %X 不带正负号的十六进制值,使用A至F表示10至15
    %% 表示"%"本身

转义符

说完了"格式替换符",再来说说"转义字符",刚才的示例中,只用到了"\n"这个转义符,还有很多其他的转义符,printf中的转义字符与其他程序中的转义字符没有什么不同,此处我们只是总结出来,方便大家使用。

  • printf常用的转义符
转义符 含义
\a 警告字符,通常为ASCII的BEL字符
\b 后退
\c 抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略
\f 换页(formfeed)
\n 换行
\r 回车(Carriage return)
\t 水平制表符
\v 垂直制表符
\ 一个字面上的反斜杠字符,即""本身。
\ddd 表示1到3位数八进制值的字符,仅在格式字符串中有效
\0ddd 表示1到3位的八进制值字符

示例

每个传入的参数添加一对"括号+空格",可以使用如下命令。

[root@node1 ~]# printf "( %s )" 1 19 28 222
( 1 )( 19 )( 28 )( 222 )[root@node1 ~]#

将每个传入的参数使用"制表符"隔开,可以使用如下命令。

[root@node1 ~]# printf "%s\t " 1 19 28 222
1	 19	 28	 222	 [root@node1 ~]#

设置多个"格式替换符"
所指定的"格式"中所包含的"格式替换符"的数量,就代表每次格式化的参数的数量,每个"格式替换符"与参数都是一一对应的,上图中,指定的"格式"中包含两个"格式替换符",那么printf每次进行"格式化"操作时,就会传入两个参数,然后前一个参数对应第一个替换符,后一个参数对应第二个替换符,当本次格式化操作完成以后,再传入下一波参数
4.printf命令详解,格式化,awk格式化,printf动作_linux_02

[root@node1 ~]# printf "%s %s\n" a b c d e f g
a b
c d
e f
g
[root@node1 ~]# printf "%s %s %s\n" a b c d e f g
a b c
d e f
g

修饰符

“数字” “+” “-”

  • 数字指定输出宽度
    4.printf命令详解,格式化,awk格式化,printf动作_脚本语言_03

"年龄"字段对应的数字都快跑到"性别"字段里面了,这个时候可以指定字段输出宽度
4.printf命令详解,格式化,awk格式化,printf动作_bash_04

上图中第一个"%7s"中间的7表示当前替换符对应的输出宽度为7个字符宽,如果对应的输出不足7个字符,则用空格补全,如果输出的长度超过7个字符,超出的部分也会显示。同理"%5s"表示当前替换符对应的输出宽度为5个字符的宽度。而这些数字,其称之为"修饰符",修饰符会对相应的"替换符"进行修饰。

  • 左对齐/右对齐
    4.printf命令详解,格式化,awk格式化,printf动作_脚本语言_05

与之前的"格式"相比,只是在原来的修饰符前面加入了"-","-“表示左对齐,默认不加”-“时表示右对齐,其实”-"也是修饰符。

  • +

除了数字和"-",还有另一种修饰符,就是"+"
"+“不代表右对齐,表达含义示是"正数"前面的"正号”

[root@node1 ~]# printf "体温\n"; printf "%+3d\n" 10 -190
体温
+10
-190
  • 小数点修饰符
    当替换符为"%f"时,数字修饰符带有小数点,则数字修饰符小数点后的数字表示对应小数精度。
[root@node1 ~]# printf "体温\n"; printf "%+3f\n" 10.1234 -190.12323
体温
+10.123400
-190.123230
[root@node1 ~]# printf "体温\n"; printf "%+3.3f\n" 10.1234 -190.12323
体温
+10.123
-190.123
awk格式化

利用awk中的printf动作,即可对文本进行格式化输出,printf动作的用法与printf命令的用法相似

示例

[root@node1 awkdir]# awk '{print $1}' awktxt3 
asdf
123
sdf

printf动作也都不会输出换行符,默认会将文本输出在一行里面。

[root@node1 awkdir]# awk '{printf $1}' awktxt3 
asdf123sdf

使用"格式替换符"来指定一下$1的格式

[root@node1 awkdir]# awk '{printf "%s\n",$1}' awktxt3 
asdf
123
sdf

注意事项

在awk中使用printf动作时,需要注意以下3点。
1)使用printf动作输出的文本不会换行,如果需要换行,可以在对应的"格式替换符"后加入"\n"进行转义。
2)使用printf动作时,"指定的格式""被格式化的文本" 之间,需要用"逗号"隔开。
3)使用printf动作时,"格式"中的"格式替换符"必须与 "被格式化的文本" 一一对应。
  • “指定的格式” 与 “被格式化的文本” 之间,需要用"逗号"隔开。
[root@node1 awkdir]# awk '{printf "%s\n",$1}' awktxt3 
asdf
123
sdf
[root@node1 awkdir]# printf "%s\n" awktxt3 
awktxt3
  • "格式"中的"格式替换符"必须与 “被格式化的文本” 一一对应

printf命令时,当指定的格式中只有一个"格式替换符",但是传入了多个参数时,那么这多个参数可以重复的使用这一个格式替换符

[root@node1 awkdir]# printf "%s\n" 1 2 3 4 5
1
2
3
4
5

但是在awk中,不能这样使用,在awk中,格式替换符的数量必须与传入的参数的数量相同,换句话说,格式替换符必须与需要格式化的参数一一对应

[root@node1 awkdir]# printf "%s\n" 1 2 3 4 5
1
2
3
4
5
[root@node1 awkdir]# awk 'BEGIN{printf "%s\n", 1,2,3,4,5}'
1
[root@node1 awkdir]# awk 'BEGIN{printf "%s\n%s\n%s\n%s\n%s\n", 1,2,3,4,5}'
1
2
3
4
5

示例

  • 利用格式替换符对文本中的每一列进行格式化
[root@node1 awkdir]# cat awktxt3
asdf wer uoiou sdfl
123 ljk3 9xds
sdf 0knm 8hjlk
[root@node1 awkdir]# awk '{printf "第一列 :%s 第二列 :%s\n" , $1,$2 }' awktxt3 
第一列 :asdf 第二列 :wer
第一列 :123 第二列 :ljk3
第一列 :sdf 第二列 :0knm
  • 利用awk的内置变量FS,指定输入字段分隔符,然后再利用printf动作,进行格式化

awk本身负责文本切割,printf动作负责格式化文本
利用awk的begin模式,结合printf动作,输出一个像样的表格。

[root@node1 awkdir]# awk -v FS=":" 'BEGIN{printf "%-10s\t %s\n","用户名称","用户id"}  {printf "%-10s\t %s\n" , $1,$3 }' /etc/passwd

总结

printf命令详解,格式化,awk格式化,printf动作