我对bash脚本有点陌生。所以,请忍受我。我正在尝试创建一个表,并像这样在for循环中分配值:
packages=("foo" "bar" "foobar")
packageMap=()
function test() {
i=0;
for package in "${packages[@]}"
do
echo $i
packageMap[$package]=$i
i=$(expr $i + 1)
done
}
test
echo the first value is ${packageMap["foo"]}
此输出为:
0
1
2
the first value is 2
我的预期输出是:
0
1
2
the first value is 0
因此,基本上将变量的引用分配给它,而不是值。该如何解决?
我的bash版本:
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin16)
TIA
答案 0 :(得分:6)
bash
3.2仅具有索引数组,因此,packageMap[$package]
仅在$package
是整数而不是任意字符串的情况下才能正常工作。
(您观察到的是$package
在算术上下文中求值,其中foo
,bar
和foobar
递归扩展,直到获得整数值为止。未定义的变量扩展为0,因此packageMap[foo]
等效于packageMap[0]
。)
如果您使用的是bash
4或更高版本,则可以使用关联数组:
packages=("foo" "bar" "foobar")
declare -A packageMap
test () {
i=0
for package in "${packages[@]}"
do
echo $i
packageMap[$package]=$i
i=$(($i + 1))
done
}
鉴于i
与packages
的每个元素的索引相同,您也可以编写
test () {
for i in "${!packages[@]}"; do
package=${packages[i]}
packageMap[$package]=$i
done
}
而不是显式增加i
。
答案 1 :(得分:0)
正如chep所说,bash 3中没有关联数组。也就是说,如果您不介意浪费一点CPU,则可以使用具有类似效果的函数:
#!/bin/bash
packages=("foo" "bar" "foobar")
function packagemap () {
local i
for i in "${!packages[@]}"; do
[[ ${packages[$i]} = $1 ]] && echo "$i" && return
done
echo "unknown"
}
echo "the first value is $(packagemap "foo")"
${!array[@]}
构造扩展为数组的索引集,对于通常不相关的数组,该索引集由从0开始的递增整数组成。但是可以删除数组成员而无需重新编号索引(即{ {1}}),因此能够引用 actual 索引而不是假定它们与简单计数的for循环是连续的很重要。