Bash 内置 printf 函数

作者:Mitch Frazier

 

即使您已经熟悉 printf 命令,如果您通过“man printf”获取信息,您可能会错过 bash 内置版本标准 printf(1) 命令提供的一些有用功能。

 

如果您不知道 bash 有自己的 printf 版本,那么您就没有注意到 printf(1) 命令的 man 手册中的注释

注意:您的 shell 可能有自己的 printf 版本,通常会取代此处描述的版本。请参阅您的 shell 文档,了解有关其支持的选项的详细信息。

您阅读了 man 手册,对吧?我必须承认,我使用 printf 相当长一段时间后才意识到 bash 有自己的版本。

要查找内置版本 printf 的文档,只需在 bash man 手册中搜索“printf”即可。

如果您完全不熟悉 printf 命令以及其他语言中的类似函数,那么几个快速示例应该能让您快速上手

$ printf "Hello world\n"
Hello world

$ printf "2 + 2 is %d\n" $((2+2))
2 + 2 is 4

$ printf "%s: %d\n" "a string" 12
a string: 12

您为 printf 提供一个格式字符串和一个值列表。然后它会替换%...字符串中的序列,并根据格式规范(百分号后面的部分)格式化列表中的值。有十几个或更多的格式说明符字符,但在 99% 的情况下,您只需要以下这些

  • d- 将值格式化为有符号十进制数。
  • u- 将值格式化为无符号十进制数。
  • x- 将值格式化为十六进制数,使用小写字母 a-f。
  • X- 将值格式化为十六进制数,使用大写字母 A-F。
  • s- 将值格式化为数字 [编辑:更正,应为“字符串”]。

格式说明符前面可以加上字段宽度,以指定要打印的最小字符数。正宽度使值右对齐;负宽度使值左对齐。以零开头的宽度使数字字段用零填充。通常,您希望对字符串使用负宽度,对数字使用正宽度。

可能不是您想要的

$ printf "%20s: %4d\n" "string 1" 12 "string 2" 122
        string 1:   12
        string 2:  122

可能仍然不是您不想要的

$ printf "%-20s: %-4d\n" "string 1" 12 "string 2" 122
string 1            : 12
string 2            : 122

这可能才是您想要的

$ printf "%-20s: %4d\n" "string 1" 12 "string 2" 122
string 1            :   12
string 2            :  122

请注意,如果 printf 用完格式说明符,它会重复使用格式,在上面的示例中,这允许您仅使用两个格式说明符打印两行(四个值)。

如果您将宽度指定为星号,则宽度取自列表中的下一个值

$ printf "%*s: %*d\n" -20 "a string" 4 12
a string            :   12

请注意,如果您想用零填充字段并且使用星号指定宽度,请将零放在星号之前

$ printf "%*s: %0*d\n" -20 "a string" 4 12
a string            : 0012

现在来说说 bash 内置版本 printf 提供的功能。第一个是 -v 选项,它允许您将格式化结果放入变量中,而不是打印出来。所以,与其使用

$ hw=$(printf "Hello world")
echo $hw
Hello world

您可以这样做

$ printf -v hw "Hello world"
echo $hw
Hello world

第二个选项用于格式化时间(和日期)

$ printf "%(%m-%d-%Y %H:%M:%S)T\n" $(date +%s)
01-10-2019 09:11:44

此处的格式说明符是%(datefmt)T值是从 纪元开始的系统时间(以秒为单位)。嵌套的 datefmt 支持与 strftime(3) 支持的相同格式选项。您可以通过指定以下内容来获取系统时间值+%sdate 命令的格式选项。

以下是

支持的几个特殊参数%(datefmt)T格式。来自 bash man 手册

可以使用两个特殊参数值:-1 表示当前时间,-2 表示 shell 被调用的时间。如果未指定参数,则转换行为就像给定了 -1 一样。

bash 的内置版本 printf 还支持一些其他功能,但您可能不需要经常使用。有关更多信息,请参阅 man 手册。

Mitch Frazier 是 Emerson Electric Co. 的嵌入式系统程序员。自 2000 年代初期以来,Mitch 一直是 Linux Journal 的贡献者和朋友。

加载 Disqus 评论