我是 Unix shell 脚本新手 我的代码如下:
i=0
for var in 'a' 'b' 'c' 'd' 'e'
do
content[i]=var
((i=`expr i+1`))
done
a=10
b=50
c=40
d=90
e=100
Now I wanted to print the local variables contents using array into the function
print_array
{
echo "${content[0]}"
echo "${content[1]}"
echo "${content[2]}"
echo "${content[3]}"
echo "${content[4]}"
}
我想要做的数组内容是 {a,b,c,d,e} 并且有一个名为 a,b,c,d,e 的局部变量,带有一些分配的值我想通过使用打印这些局部变量数组的名称,因为数组元素和局部变量元素的名称相同,因此我尝试通过尝试 $ 和 array_names 的多种组合来通过引用调用,但不起作用
答案1
所以我首先定义一个间接打印函数......
_print() while [ "$#" -ne 0 ]
do printf '$%s = %d\n' \
"$1" "$(($1))"
shift
done
接下来我将设置数组并递增......
arr=( a b c d e ); i=0
for var in "${arr[@]}"
do : "$(($var=(i+=10)))"
done
所以现在 的值$a
是 10 和$b
20 等等。最后只剩下打印了...
_print "${arr[@]}"
...打印到标准输出...
$a = 10
$b = 20
$c = 30
$d = 40
$e = 50
所有这些之所以有效,是因为 shell 处理$((
数学))
扩展的方式 - 它们基本上是eval
s。在算术展开式中,shell第一的扩大任何在尝试进行数学计算之前进行其他有效的 shell 扩展 - 使实际数学成为最后的任务。
这意味着如果您这样做:
i=a a=10; echo "$(($i))"
打印的结果是10
因为 shell 扩展了$i
to get的值a
然后求值那结果作为整数参考。
上面的代码可以在任何兼容 POSIX 的 shell 中运行。
这意味着我也可能做了......
i=10
for var in a b c d e
do arr[($var=i*${#arr[@]}+i)/i]=$var
done
$var
...同时处理数组赋值、索引求值和整数赋值,因为命名 shell 数组的[
索引]
括号(在支持它们的 shell 中)与数学表达式的$((
扩展括号相同。))
运行包含在命令中的上述代码ksh -xc
会将以下调试输出打印到标准错误:
+ arr[1]=a
+ arr[2]=b
+ arr[3]=c
+ arr[4]=d
+ arr[5]=e
从那里我可以做:
echo "$((${arr[1]}))"
echo "$((a))"
...打印...
10
10
...因为它们在支持命名数组的 shell 中求值相同。然而,在不...
echo 'arr=(a b c d e)' | bash -x
+ arr=(a b c d e) #bash traces the successful command to stderr
echo 'arr=(a b c d e)' | sh -x
sh: 1: Syntax error: "(" unexpected #sh traces something else
所以在_print()
函数中我只是shift
在位置参数上(代表真正的便携式贝壳"$@"
阵列)虽然有任何并且printf
......
- 首先是
$
美元符号。 - 然后
%s
将 tring 值存储在我的$1
st 位置参数中。 - 然后是
=
等号。 - 最后将值存储在值存储在我的
$(($1))
第一个位置参数。
当函数shift
的参数消失时,第一个位置参数不断地被下一个位置参数替换,直到$#
位置参数计数等于 0 并且函数返回。
在运行函数之前,当我初始化数组及其组成的间接变量时,其工作方式如下:
for var in "${arr[@]}"
- shell 将扩展
[@]
为列表参数和[*]
该列表的单个串联。如果扩展没有被引用的话可能也扩展到一个列表 - 取决于完成时[*]
是否有值以及当前如何配置 ilename 扩展 - 但如果这样做,它可能不会按照您想要的方式进行。$IFS
set -f
- shell 将扩展
: "$(($var=(i+=10)))"
- 中的每个值依次
${arr[@]}
分配给 的值。然后被扩展$var
$(($var=(i+=10)))
第一的$var
对于like中的值$((a=(i+=10)))
,最后完成所有数学运算 - 首先递增$i
10,然后将值赋给$i
to$a
。
- 中的每个值依次
答案2
尝试
#i=0
for var in 'a' 'b' 'c' 'd' 'e'
do
content[${#content[*]}]=$var # or content[i++]=$var
done
# or just content=( 'a' 'b' 'c' 'd' 'e' )
a=10
b=50
c=40
d=90
e=100
for i in "${#content[@]}"
do
echo ${!i}
done
答案3
如果我理解正确的话,您需要在变量访问中进行间接访问,例如bash
.有了这个代码:
content=( a b c d e )
a=10
b=50
c=40
d=90
e=100
echo "${!content[0]}"
echo "${!content[1]}"
echo "${!content[2]}"
echo "${!content[3]}"
echo "${!content[4]}"
你会得到这样的结果:
10
50
40
90
100
这里的关键是bash
具体的变量扩展访问方法"${! ... }"
。