首先抱歉,因为我的英语可能不好。 我想使用变量来索引数组中的元素,或者使用相同的变量来索引所有元素。例如:
Coordinate c = new Coordinate(40.465, -75.089);
//Display DMS Format
c.FormatOptions.Format = CoordinateFormatType.Degree_Minutes_Seconds;
c.ToString();//N 40º 27' 54" W 75º 5' 20.4"
c.Latitude.ToString();//N 40º 27' 54"
c.Latitude.ToDouble();//40.465
当我使用 var1 在 $ {array [$ var1]} 中编制索引时,它可以正常工作,但如果我使用 var2 无法正常工作,我收到此错误:
...
var1="1"
var2="*"
array=(one two three for five)
for elem in ${array[$var1]}
do
echo $elem
done
我很确定该错误与*通配符扩展有关,但我没有找到帮助我解决此问题的答案。那么,我该怎么做呢?
答案 0 :(得分:4)
*
和@
不被视为数组中的常规元素。迭代键时不会列出它们,并且在通过索引变量间接扩展时不会考虑它们。
bash source code有一个chk_atstar
函数可以检查[@]
或[*]
是否正在使用,你可以看到它是按字面意思完成的,而不是通过任何扩张:
else if (valid_array_reference (name, 0))
{
temp1 = mbschr (name, '[');
if (temp1 && temp1[1] == '@' && temp1[2] == ']')
{
如果你真的想这样做,你可以通过变量间接:
arr=(one two three)
index='*'
var="arr[$index]"
echo "${!var}"
尽管您最好不要将这些特殊的数组访问模式视为数组元素。
答案 1 :(得分:1)
我不建议这样做,但为了完整起见,您可以使用eval
欺骗扩展订单来实现此目的:
eval items=\${array[$var2]}
for elem in $items
do
echo $elem
done
这有问题。 eval
通常发音为'#34; evil"因为从变量运行代码可能会产生安全隐患。与使用eval
相比,通常有更好的方法来完成工作。在这种情况下,您应该考虑一下设计。
如果元素包含嵌入的空格,也会出现问题。添加:
array+=('at the end')
在数组声明之后,你会明白我的意思。
编辑:经过一番考虑,这里有一种方法没有 eval
,它支持嵌入空格或制表符(但不支持嵌入的换行符)。漂亮不是:
display_it() {
if [[ $1 = '*' ]]; then
oldIFS="$IFS"
IFS=$'\n'
echo "${array[*]}"
IFS="$oldIFS"
else
echo "${array[$1]}"
fi
}
var1="1"
var2="*"
array=(one two three for five)
array+=('at the end')
while read -r elem
do
echo $elem
done < <(display_it "$var2")
显示器:
one
two
three
for
five
at the end
在循环结束时,您将看到进程替换,其中我调用函数display_it
。读取的每个项目由换行符分隔,因此在函数中交换内部字段分隔符(IFS
)。