Bash 数组上的间接

Ray*_*Ray 4 bash array

是否有可能在没有循环的情况下编写以下脚本?

IPv4_first=1.1.1.1
IPv4_second=2.2.2.2
IPv4_third=3.3.3.3

IPv4_all=() 

for var in ${!IPv4_@}
do
   IPv4_all+=(${!var})
done

printf "'%s'\n" "${IPv4_all[@]}"
Run Code Online (Sandbox Code Playgroud)

就像是:

IPv4_all=${!${!IPv4_@}}
Run Code Online (Sandbox Code Playgroud)

Mic*_*mer 5

这可能是我写过的最丑陋的 Bash 代码,但是......

IPv4_first=1.1.1.1
IPv4_second=2.2.2.2
IPv4_third=3.3.3.3

names=(${!IPv4_@})
eval "IPv4_all=(${names[@]/#/$})"
printf "'%s'\n" "${IPv4_all[@]}"
Run Code Online (Sandbox Code Playgroud)

看马,没有循环!

${names[@]/#/$}预规划 $到所述阵列的每个元素的开始时,通过匹配锚固到每个元素的开始为空字符串。这给出了一个变量解引用数组,我们可以在内部扩展它eval以获取数组初始化器中的变量引用。这些需要是两个单独的行,因为您不能同时应用多个参数扩展。

输出是:

'1.1.1.1'
'2.2.2.2'
'3.3.3.3'
Run Code Online (Sandbox Code Playgroud)

正如预期的那样。

可以用以下内容替换该行:

IPv4_all=($(eval "echo ${names[@]/#/$}"))
Run Code Online (Sandbox Code Playgroud)

而不是evalling 数组分配。我不确定这是否更好。

如果您的变量值可能包含空格或其他 IFS 字符,您可以更改 eval:

eval "IPv4_all=($(printf '"$%s" ' "${names[@]}"))"
Run Code Online (Sandbox Code Playgroud)

这正确地双引号所有变量取消引用。