Shell的printf格式化输出怎么用
printf 能按格式输出字符串:%s字符串、%d整数、%f浮点数。格式是 %[对齐][补位][长度].[小数位][类型],比如 %-10s 左对齐10位,%010d 右对齐左补0共10位,%09.2f 是9位保留2位小数左补0。写 Shell 脚本处理数据时很常用。
上一次用 printf 还是上一次,哈哈哈~
之前写 Shell 脚本做数据库割接,时间紧,网上搜了个 printf 命令直接抄过来用,当时压根没深究它每个符号啥意思。
后来回头补课才发现,这命令在 Shell 里相当实用。
写 JAVA 我们说万物皆对象,整天跟对象打交道。那 Shell 脚本呢,本质上就是在跟字符串较劲。
既然要摆弄字符串,格式化就躲不开——补零、对齐、留几位小数,全靠它。这篇把 printf 的玩法摊开讲一讲。
printf 是干嘛的
echo 大家都熟,输出一行字。
但 echo 没法控制格式,想让数字补齐成固定宽度、想对齐成一列,它就无能为力了。
printf 就是来干这个的:按你指定的格式把内容输出。
它跟 C 语言的 printf 几乎一个路子,用过 C 的会很眼熟。
基本结构长这样:
# 第一个参数是格式串,后面是要往里填的值
printf "格式串" 值1 值2 ...
重点全在"格式串"里,剩下的都是往格式里填空。
格式串怎么拆
格式串里的核心是以 % 开头的占位符,一个完整的占位符可以拆成这几段:
% [对齐] [补位] [宽度].[小数位] [类型]
听着抽象,直接上实例最快(我一向觉得列一堆说明不如跑一遍):
# 左对齐,总宽10位,右边补空格,结果:[mebugs ]
printf "%-10s" "mebugs"
# 右对齐(默认),总宽10位,左边补空格,结果:[ mebugs]
printf "%10s" "mebugs"
# 右对齐,总宽10位,左边补0,结果:[0000000123]
printf "%010d" "123"
# 总宽9位,保留2位小数,左补0,结果:[000123.00]
printf "%09.2f" "123"
拆开看 %09.2f:
%起手。0表示不足宽度时补 0(默认补空格)。9是总宽度,含小数点和小数位。.2是保留 2 位小数。f表示按浮点数输出。
把这几段的含义记住,剩下就是排列组合。
常用的类型符
格式串里的类型字母决定了值怎么被解读,常用的几个:
%s:字符串,最常用。%d/%i:十进制整数。%f:浮点数,配.n控制小数位。%e/%g:科学计数法形式的浮点。%o:八进制。%x:十六进制(小写 a~f)。%c:单个字符。%%:输出一个字面的百分号%。
再加两个修饰:
-:放在%后面表示左对齐,不写就是右对齐。0:宽度前加 0 表示用 0 补位。
实战里的小坑
有个点容易忘:printf 不像 echo 会自动换行。
# 这样连着打,输出会黏在一起:mebugs老王
printf "%s" "mebugs"
printf "%s" "老王"
# 想换行得自己在格式串里加 \n
printf "%s\n" "mebugs"
printf "%s\n" "老王"
还有个好用的特性:格式串会循环套用到后面所有的值上。
# 一个格式串,三个值,格式会重复用三次,每个值占一行
printf "%-8s\n" "老王" "老张" "王阿姨"
# 输出:
# 老王
# 老张
# 王阿姨
这个在批量格式化一列数据时特别省事。
printf 搞不定的情况
printf 虽好,也有它够不着的地方。
比如数字右边补 0(不是左边),或者补的不是 0 而是指定字符,printf 就没有直接的写法。
这时候可以搬出 awk 来凑:
# 把 121 右侧补 0 到总宽 10 位
echo 121 | awk '{
width = 10
printf("%d", $1) # 先原样打出数字本身
for (i = 0; i < width - length($1); i++) # 缺多少位就补多少个 0
printf "0"
print "" # 收尾换个行
}'
# 输出:1210000000
awk 也是个神器,能干的事比这多得多,下次单开一篇聊,哈哈~
小结
printf 在 Shell 里就是专门管格式化输出的,核心就一个格式串。
记住 % [对齐] [补位] [宽度].[小数位] [类型] 这个结构,常见的 %-10s、%010d、%09.2f 自己就能拼出来。
别忘了它不自动换行,格式串得自己带 \n;格式串还会循环套用到多个值上,批量处理很香。
遇到右补零这种 printf 搞不定的,退一步用 awk 兜底。
那就打开终端自己敲几行试试吧,比看十遍都记得牢。
