如果索引号为
@
或*
,则引用数组的所有成员。
当我这样做时:
LIST=(1 2 3)
for i in "${LIST[@]}"; do
echo "example.$i"
done
它给出了所需的结果:
example.1
example.2
example.3
但是当我使用时${LIST[*]}
,我得到
example.1 2 3
反而。
为什么?
编辑:当使用printf
, 时,@
实际上*
确实给出了相同的结果。
答案1
差异是微妙的;"${LIST[*]}"
(like "$*"
) 创建一个参数,而"${LIST[@]}"
(like "$@"
) 会将每一项扩展为单独的参数,因此:
LIST=(1 2 3)
for i in "${LIST[@]}"; do
echo "example.$i"
done
将把列表作为多个变量来处理(打印它)。
但:
LIST=(1 2 3)
for i in "${LIST[*]}"; do
echo "example.$i"
done
会将列表作为一个变量来处理。
答案2
使用[*]
将创建单个字符串,数组的每个元素都与$IFS
元素之间的第一个字符(默认为空格)连接起来。
使用[@]
将创建一个列表。
例子:
创建数组:
$ list=( a b "big fish" c d )
单独打印每个元素:
$ printf 'data: ---%s---\n' "${list[@]}"
data: ---a---
data: ---b---
data: ---big fish---
data: ---c---
data: ---d---
创建单个字符串并打印:
$ printf 'data: ---%s---\n' "${list[*]}"
data: ---a b big fish c d---
再次,但使用自定义分隔符:
$ IFS='/'
$ printf 'data: ---%s---\n' "${list[*]}"
data: ---a/b/big fish/c/d---
请注意,使用这些扩展没有双引号很少有意义。
如果 的第一个字符是多字节字符,或者是无法解码为字符的字符,则如果$IFS
未设置(在之后IFS=
),则如果$IFS
未设置(在之后),则没有任何内容,但 shell 之间存在一些差异。unset -v IFS
$IFS
答案3
考虑列表元素不包含特殊字符(例如空格)的简单情况。然后可以删除引号。那么@和*会给出相同的结果。
LIST=(1 2 3)
for i in ${LIST[*]}; do
echo "example.$i"
done
输出:
example.1
example.2
example.3
现在考虑元素包含空格的情况:
LIST=(1 "a b" 3)
for i in ${LIST[*]}; do
echo "example.$i"
done
在这种情况下,@和*仍然给出相同的结果:
example.1
example.a
example.b
example.3
但这不是我们想要的,因为“a b”被分割为两个元素而不是一个元素。所以我们需要使用引号来防止这种情况:
LIST=(1 "a b" 3)
for i in "${LIST[*]}"; do
echo "example.$i"
done
但结果是example.1 a b 3
。接下来我们将*改为@:
LIST=(1 "a b" 3)
for i in "${LIST[@]}"; do
echo "example.$i"
done
最终我们得到了想要的结果:
example.1
example.a b
example.3
总结上述结果,我们看到 @ 在被某些运算符(例如引号)操作时允许逐元素操作。