前言
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 ~]# 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命令,而每个被传入的参数都会按照指定的"格式"被"格式化"。
命令中的"%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常用的转义符
示例
每个传入的参数添加一对"括号+空格",可以使用如下命令。
[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每次进行"格式化"操作时,就会传入两个参数,然后前一个参数对应第一个替换符,后一个参数对应第二个替换符,当本次格式化操作完成以后,再传入下一波参数
[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
修饰符
“数字” “+” “-”
数字指定输出宽度
"年龄"字段对应的数字都快跑到"性别"字段里面了,这个时候可以指定字段输出宽度
上图中第一个"%7s"中间的7表示当前替换符对应的输出宽度为7个字符宽,如果对应的输出不足7个字符,则用空格补全,如果输出的长度超过7个字符,超出的部分也会显示。同理"%5s"表示当前替换符对应的输出宽度为5个字符的宽度。而这些数字,其称之为"修饰符",修饰符会对相应的"替换符"进行修饰。
左对齐/右对齐
与之前的"格式"相比,只是在原来的修饰符前面加入了"-","-“表示左对齐,默认不加”-“时表示右对齐,其实”-"也是修饰符。
+
除了数字和"-",还有另一种修饰符,就是"+"
"+“不代表右对齐,表达含义示是"正数"前面的"正号”
[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