Bash脚本 - 通过“变量”变量名称迭代关联数组列表

时间:2021-07-20 12:48:09

I've got a variable list of associative arrays that I want to iterate through and retrieve their key/value pairs.

我有一个关联数组的变量列表,我想迭代并检索它们的键/值对。

I iterate through a single associative array by listing all its keys and getting the values, ie.

我通过列出其所有键并获取值来迭代单个关联数组,即。

for key in "${!queue1[@]}" do
    echo "key : $key"
    echo "value : ${queue1[$key]}"
done

The tricky part is that the names of the associative arrays are variable variables, e.g. given count = 5, the associative arrays would be named queue1, queue2, queue3, queue4, queue5.

棘手的部分是关联数组的名称是变量变量,例如给定count = 5,关联数组将命名为queue1,queue2,queue3,queue4,queue5。

I'm trying to replace the sequence above based on a count, but so far every combination of parentheses and eval has not yielded much more then bad substitution errors. e.g below:

我试图根据计数替换上面的序列,但到目前为止,括号和eval的每个组合都没有产生更多的错误替换错误。例如:

for count in {1,2,3,4,5} do
    for key in "${!queue${count}[@]}" do
        echo "key : $key"
        echo "value : ${queue${count}[$key]}"
    done
done

Help would be very much appreciated!

非常感谢帮助!

3 个解决方案

#1


3  

The difficulty here stems from the fact that the syntax for indirect expansion (${!nameref}) *es with the syntax for extracting keys from an associative arrays (${!array[@]}). We can have only one or the other, not both.

这里的困难源于间接扩展($ {!nameref})的语法与从关联数组($ {!array [@]})中提取键的语法冲突的事实。我们只能有一个,而不是两个。

Wary as I am about using eval, I cannot see a way around using it to extract the keys of an indirectly referenced associative array:

我担心使用eval时,我看不到使用它来提取间接引用的关联数组的键的方法:

keyref="queue${count}[@]"
for key in $(eval echo '${!'$keyref'}'); do ... ; done

You can however avoid eval and use indirect expansion when extracting a value from an array given the key. Do note that the [key] suffix must be part of the expansion:

但是,在给定键的数组中提取值时,可以避免使用eval并使用间接扩展。请注意,[key]后缀必须是扩展的一部分:

valref="queue${count}[$key]"
echo ${!valref}

To put this in context:

把它放在上下文中:

for count in {1..5} ; do
    keyref="queue${count}[@]"
    for key in $(eval echo '${!'$keyref'}'); do
        valref="queue${count}[$key]"
        echo "key = $key"
        echo "value = ${!valref}"
    done
done

#2


1  

I was able to make it work with the following script:

我能够使用以下脚本:

for count in {1..5} ; do
    for key in $(eval echo '${!q'$count'[@]}') ; do
        eval echo '${q'$count"[$key]}"
    done
done

Note it breaks if any key contained a space. If you want to deal with complex data structures, use a more powerful language like Perl.

请注意,如果任何键包含空格,则会中断。如果您想处理复杂的数据结构,请使用更强大的语言,如Perl。

#3


0  

I think this might work (but untested). The key is to treat the indexing as the full name of a variable. (That is, the array queue5 can be treated as a sequence of variables named queue5[this], queue5[that], etc.)

我认为这可能有效(但未经测试)。关键是将索引视为变量的全名。 (也就是说,数组queue5可以被视为名为queue5 [this],queue5 [that]等的变量序列。)

for count in {1,2,3,4,5} do
    assoc="queue$count[@]"
    for key in "${!assoc}" do
        echo "key : $key"
        val="queue$count[$key]"
        echo "value : ${!val}"
    done
done

#1


3  

The difficulty here stems from the fact that the syntax for indirect expansion (${!nameref}) *es with the syntax for extracting keys from an associative arrays (${!array[@]}). We can have only one or the other, not both.

这里的困难源于间接扩展($ {!nameref})的语法与从关联数组($ {!array [@]})中提取键的语法冲突的事实。我们只能有一个,而不是两个。

Wary as I am about using eval, I cannot see a way around using it to extract the keys of an indirectly referenced associative array:

我担心使用eval时,我看不到使用它来提取间接引用的关联数组的键的方法:

keyref="queue${count}[@]"
for key in $(eval echo '${!'$keyref'}'); do ... ; done

You can however avoid eval and use indirect expansion when extracting a value from an array given the key. Do note that the [key] suffix must be part of the expansion:

但是,在给定键的数组中提取值时,可以避免使用eval并使用间接扩展。请注意,[key]后缀必须是扩展的一部分:

valref="queue${count}[$key]"
echo ${!valref}

To put this in context:

把它放在上下文中:

for count in {1..5} ; do
    keyref="queue${count}[@]"
    for key in $(eval echo '${!'$keyref'}'); do
        valref="queue${count}[$key]"
        echo "key = $key"
        echo "value = ${!valref}"
    done
done

#2


1  

I was able to make it work with the following script:

我能够使用以下脚本:

for count in {1..5} ; do
    for key in $(eval echo '${!q'$count'[@]}') ; do
        eval echo '${q'$count"[$key]}"
    done
done

Note it breaks if any key contained a space. If you want to deal with complex data structures, use a more powerful language like Perl.

请注意,如果任何键包含空格,则会中断。如果您想处理复杂的数据结构,请使用更强大的语言,如Perl。

#3


0  

I think this might work (but untested). The key is to treat the indexing as the full name of a variable. (That is, the array queue5 can be treated as a sequence of variables named queue5[this], queue5[that], etc.)

我认为这可能有效(但未经测试)。关键是将索引视为变量的全名。 (也就是说,数组queue5可以被视为名为queue5 [this],queue5 [that]等的变量序列。)

for count in {1,2,3,4,5} do
    assoc="queue$count[@]"
    for key in "${!assoc}" do
        echo "key : $key"
        val="queue$count[$key]"
        echo "value : ${!val}"
    done
done