为什么 printf "${array[@]}\n" 不打印数组的所有元素?

Why doesn't printf "${array[@]}\n" print all elements of my array?

我在一个名为 pwd_ids 的数组中有一些值,当我尝试使用 printf 打印所有值时它只给出第一个元素,而尝试使用 echo 打印时它给出所有元素。这背后的原因是什么。下面给出了我的例子。

set -A pwd_ids  E.1.1.7 E.1.1.9 E.1.1.2 E.1.1.3 E.1.1.4 E.1.1.6 E.1.1.5 
echo "${pwd_ids[@]}"
printf "${pwd_ids[@]}\n"

输出:

 E.1.1.7 E.1.1.9 E.1.1.2 E.1.1.3 E.1.1.4 E.1.1.6 E.1.1.5
 E.1.1.7

printf 的第一个参数是 格式字符串 。数据应仅在 后续 个参数中传递。因此:

printf '%s\n' "${pwd_ids[@]}"

将正确发出:

E.1.1.7
E.1.1.9
E.1.1.2
E.1.1.3
E.1.1.4
E.1.1.6
E.1.1.5

也可以使用其他格式字符串;例如,要在项目前面加上破折号打印您的项目,您可以使用:printf ' - %s\n' "${pwd_ids[@]}";或者将两个列打印成一行,填充到 20 spaces,printf '%20s%20s\n' "${pwd_ids[@]}"


或者,要将所有值放在一行中,将它们全部传递到单个后续参数中:

printf '%s\n' "${pwd_ids[*]}"

输出(如果您的 IFS 变量是默认值或以 space 开头):

E.1.1.7 E.1.1.9 E.1.1.2 E.1.1.3 E.1.1.4 E.1.1.6 E.1.1.5

解释以上所有内容:后续参数替换格式字符串中的占位符。在上面的第一种情况下,数组的每个元素都根据 %s\n 进行评估,因此在它之后立即添加了一个换行符。

在您的问题中,您将 E.1.1.7 作为格式字符串传递。这个格式字符串根本没有占位符,所以 shell 对它的作用是未定义的:在您的 ksh 版本中,它单独打印格式字符串并忽略后续参数;在其他 shell 中,它可能会为每个参数打印一次格式字符串 (E1.1.7),忽略这些参数的值。