在执行“ printf H%03s 3A”时,printf添加尾随空格而不是0

时间:2019-06-18 12:26:10

标签: bash printf

在我的本地Mac上,我开发了一个使用printf的bash脚本。 printf在这里按预期运行:

$ printf H%03s 3A
H03A

字符串3A被扩展为3个字符,前导零。 H放在变量之前。

在部署bash脚本的地方,printf的行为有所不同:

$ printf H%03s 3A
H 3A

我只能假定内部03A被当作八进制值,因此将0删除。我该如何解决?

流行版本:

在我的本地Mac上,我有bash 5:

$ echo "$BASH_VERSION"
5.0.3(1)-release

在远程计算机上,我有bash 4:

$ echo "$BASH_VERSION"
4.2.46(2)-release

2 个答案:

答案 0 :(得分:2)

printf猛击bultin意在跟随posix printf。 posix printf实用程序在XKB File Format Notation之后,但有一些例外。

好吧,在XKB文件格式表示法中,我们可以看到:

  

标志字符及其含义为:

     

0
  对于a,A,d,e,E,f,F,g,G,i,o,u,x和X转换说明符,应使用前导零(在任何符号或基数指示之后)填充到字段宽度,而不执行空格填充,除非转换无穷大或NaN。如果同时出现“ 0”和“-”标志,则应忽略“ 0”标志。对于d,i,o,u,x和X转换说明符,如果指定了精度,则应忽略“ 0”标志。对于其他转换说明符,行为是不确定的。

0转换说明符的标志s行为未定义。

  

我只能假定内部03A被当作八进制值,因此将0删除。

不,它不解释为八进制数字。

  

我该如何解决?

我想出的最简单的方法是用零代替空间:

printf 'H%5s' "$(printf "%5s" 3A | tr ' ' '0')"

这很简单,但是如果字符串中有空格,肯​​定会失败。因此,我们需要测量字符串长度,并在字符串前面输出许多零,例如ex。像这样的东西:

printf 'H%5s' "$(str=3A; seq $((5 - ${#str})) | xargs printf '0%.0s'; printf "%s" "$str")"

答案 1 :(得分:2)

  

对于a,A,d,e,E,f,F,g,G,i,o,u,x和X转换说明符,前导零(在任何符号或基数指示之后)应用于填充到字段宽度

     

对于其他转换说明符,其行为是不确定的。

%s与0填充不兼容。