我需要有关 bash 扩展的帮助。
我想检索数组值,GNU bash 5.1.0。数组名称应该是一个变量。 “只是”引用 bash 中的变量。
我有一个名为“armin”的数组,其名称位于变量 $gral 中(工作正常):
gral="armin"
赋值:
declare -a ${gral}[1]="milk"
declare -a ${gral}[2]="cow"
declare ${gral}[7]="budgie"
declare ${gral}[9]="pla9ne"
美好的。
数组存在:
$ echo ${armin[@]}
milk cow budgie pla9ne
数组索引存在:
$echo ${!armin[@]}
1 2 7 9
数组和索引都很好。
我想通过引用它来检索数组名称作为变量,而不是手动。有很多...
变量之前已设置和使用:
$ echo $gral
armin ## name of our bash array
很好——到目前为止。
只是为了显示差异而不使用变量:
echo ${armin[@]}
milk cow budgie pla9ne
现在尝试引用变量(gral)来调用名称(armin):
$ echo ${$gral[@]}
-bash: ${$gral[@]}: wrong substitution.
$echo ${"$gral"[@]}
-bash: ${"$gral"[@]}: wrong substitution.
echo ${"gral"[@]}
-bash: ${"gral"[@]}: wrong substitution.
echo ${${gral}[@]}
-bash: ${${gral}[@]}: wrong substitution.
全部失败。也尝试了“eval”。使用关联(声明 -A)没有什么区别。
备注:索引以这种方式工作正常,没有问题。名字是问题。
我想我错过了一些东西。也许答案之前已经描述过,我发现了很多关于数组中的变量的有趣的东西,但没有识别出我的挑战的答案。
你可以吗请帮我找到通过将数组名称引用为变量来检索数组的术语?
答案1
使用 namerefs(在 Bash >= 4.3 中):
$ armin=(foo bar doo)
$ declare -n gral=armin # 'gral' references array 'armin'
$ gral[123]=quux # same as 'armin[123]=quux'
$ echo "${gral[@]}"
foo bar doo quux
$ echo "${gral[1]}"
bar
$ echo "${!gral[@]}" # listing the indexes works too
0 1 2 123
也可以看看:bash 是否支持使用指针?
答案2
正如@ilkkachu 的回答,namerefs 是这里使用的工具。它们使得将数组传递给函数变得非常容易。例如:
dumpArray() {
local -n ary=$1
for i in "${!ary[@]}"; do
printf "%s\t%s\n" "$i" "${ary[$i]}"
done
}
该函数可以处理数组和关联数组:
$ declare -a armin=([1]=milk [2]=cow [7]=bugle [9]=pla9ne)
$ dumpArray armin
1 milk
2 cow
7 bugle
9 pla9ne
$ declare -A map=([foo]=bar [baz]=qux)
$ dumpArray map
foo bar
baz qux
唯一真正的问题是,让 nameref 引用同名的数组会很混乱:
$ ary=(a b c)
$ dumpArray ary
bash: local: warning: ary: circular name reference
bash: warning: ary: circular name reference
bash: warning: ary: circular name reference
bash: warning: ary: circular name reference
bash: warning: ary: circular name reference
0 a
bash: warning: ary: circular name reference
bash: warning: ary: circular name reference
1 b
bash: warning: ary: circular name reference
bash: warning: ary: circular name reference
2 c
所以在函数中,你让数组有一个奇怪的名字,比如
dumpArray() {
local -n __dumpArray_ary=$1
do_stuff_with "${__dumpArray_ary[@]}"
}
答案3
[@]
在包含名称的变量中包含“索引”,即:
ref=$gral'[@]'
printf '%s\n' "${!ref}"
输出:
milk
cow
budgie
pla9ne
它也适用于包含空格的值。
答案4
好吧,
答案是通过作为变量传递的名称取消引用数组(部分类似于指针)
是(重复使用上面的示例):
eval echo "\$$(eval echo "{$gral[@]}")"
$gral 保存数组名称
结果:
奶牛虎皮鹦鹉 pla9ne
您现在可以扩展此解决方案以使用索引条目迭代 bash 数组(索引和关联)内容。
很高兴我找到了答案。感谢大家的帮助!
访问变量内容的内容。
在abs-guide中有导致结果的提示:
https://tldp.org/LDP/abs/html/abs-guide.html#IVR
感谢孟德尔·库珀 (Mendel Cooper) 的贡献;非常感谢我们有这份伟大的礼物,名为高级 Bash 脚本指南。
好吧,
出于安全考虑,评估很难看。
尝试找到一个更好的...