使用 `printf` 打印包含 `%` 百分号的变量会导致“bash: printf: `p': 无效格式字符”

使用 `printf` 打印包含 `%` 百分号的变量会导致“bash: printf: `p': 无效格式字符”

我想用它printf来打印一个变量。该变量可能包含%百分号。

最小的例子:

$ TEST="contains % percent"
$ echo "${TEST}"
contains % percent
$ printf "${TEST}\n"
bash: printf: `p': invalid format character
contains $

echo提供所需的输出。)

答案1

printf以正常形式使用:

printf '%s\n' "${TEST}"

man printf

SYNOPSIS
printf FORMAT [ARGUMENT]...

你应该绝不将变量传递给 FORMAT 字符串,因为它可能会导致错误和安全漏洞。


顺便提一句:

如果您想将%符号作为格式的一部分,则需要输入%%,例如:

$ printf '%d%%\n' 100
100%

答案2

您永远不应该将变量内容放入给定的格式字符串中printf。使用这个代替:

printf '%s\n' "${TEST}"

答案3

printf接受一个保证参数,然后根据您传递的内容接受一系列附加参数。所以像这样:

printf '%07.2f' 5

变成:

0005.00

第一个参数称为“ format”,始终存在。如果它不包含%字符串,则简单地打印它。因此:

printf Hello

简单地生成(值得注意的是,在默认模式下不会添加Hello尾随换行符)。echo当你期望你的例子能够发挥作用时,你已经被你自己之前(不知情的)滥用这一事实所误导了;因为您只将不带%s 的字符串传递给format,从printf的角度来看,您一直要求它输出不需要替换的内容,因此它的功能与echo -ne.

如果你想这样做正确的printf,您可能想开始使用 的内置替换功能形成可打印字符串。像这样的行出现在我的代码中:

printf '%20s: %6d %05d.%02d%%' "$key" $val $((val/max)) $((val*100/max%100))

如果你想让你现在正在做的事情发挥作用,你需要echo -ne像这样:

TEST="contains % percent"
echo -ne "${TEST}\n"

\这保留了解释变量内部转义的(有问题的)行为。提供-n然后粘上背面似乎也有点愚蠢\n,但我提供它是因为它是一个全局查找和替换,您可以将其应用于您当前正在做的所有事情。仍然使转义在变量中工作的更干净的版本\是:

TEST="contains % percent"
echo -e "$TEST"

相关内容