![为什么在bash中使用printf用@打印数组只打印第一个元素?](https://linux22.com/image/230788/%E4%B8%BA%E4%BB%80%E4%B9%88%E5%9C%A8bash%E4%B8%AD%E4%BD%BF%E7%94%A8printf%E7%94%A8%40%E6%89%93%E5%8D%B0%E6%95%B0%E7%BB%84%E5%8F%AA%E6%89%93%E5%8D%B0%E7%AC%AC%E4%B8%80%E4%B8%AA%E5%85%83%E7%B4%A0%EF%BC%9F.png)
我有一个数组
snapshots=(1 2 3 4)
当我跑步时
printf "${snapshots[*]}\n"
它按预期打印
1 2 3 4
但当我跑步时
printf "${snapshots[@]}\n"
它只是打印
1
没有换行符。我的理解是,访问数组@
应该会扩展数组,因此每个元素都在换行符上,但它似乎不会这样做,printf
而它确实会这样做echo
。为什么是这样?
答案1
printf
将其第一个参数解释为格式字符串,并打印它;任何其他参数仅根据格式字符串中的需要使用。
对于printf "${snapshots[*]}\n"
,第一个参数是数组的元素,与第一个字符$IFS
(默认为空格)连接,后跟反斜杠和n
: "1 2 3 4\n"
。打印显示数组中用空格分隔并后跟换行符的所有值。
对于printf "${snapshots[@]}\n"
,第一个参数是数组中的第一个条目 ,"1"
数组的其余部分作为单独的参数提供给要使用的格式字符串。最后一个参数已\n
附加:"2" "3" "4\n"
。由于格式字符串不引用任何其他参数,因此它们都将被忽略。所有输出都是第一个值,后面没有换行符。
要在使用时查看所有值@
,您需要提供实际的格式字符串:
printf "%s\n" "${snapshots[@]}"
包含参数引用的格式字符串会根据需要重复多次,以消耗所有参数。因此,单个引用足以打印数组中的所有值,这里每个值后跟一个换行符。