【问题标题】:How to use a variable's value as identifier in order to declare/modify an array in BASH?如何使用变量的值作为标识符来声明/修改 BASH 中的数组?
【发布时间】:2021-03-08 13:29:53
【问题描述】:

我会尽力解释:

我正在编写一个 bash 脚本并且我在一个 for 循环中。对于all 循环,我得到了一个变量VAR_ID,它用于存储另一个变量的标识符,当所有工作完成时,该变量将被导出。对于每一个循环,我得到了一个变量VALVAL 的值应分配给 VAR_ID 的值。最后,VAR_ID 的值必须是一个数组才能存储所有值。

呼……嗯,这对我来说有点难以解释,但我认为这个简单的脚本应该能阐明我想要做什么(当然,它的实际目的已经缩小了):

#!/bin/bash

COUNT=0
VAR_ID="my_array"
declare -a "$VAR_ID"

while (( $COUNT <= 2 ))
do
    VAL=$RANDOM
    $VAR_ID+=( "$VAL" )    # this doesn't work
    (( COUNT++ ))
done

export $VAR_ID

这应该会产生一个变量my_array 和其中的三个随机值。我尝试像在declare $VAR_ID=$VAL 中一样使用declare,但是如果我使用+= 而不是=,这将不再有效。 COUNT 可以在可能的解决方案中用作位置编号,或者如果它有帮助,因为我在我的原始脚本中也有它。

提前感谢您的帮助

编辑:我知道eval 有可能,但我尽量避免使用它,直到没有其他方法。

【问题讨论】:

  • 参见this answer,tl;dr:将 VAR_ID 设为 nameref。
  • 也许我不明白你的意思。但是 nameref 并没有真正的帮助,因为我已经能够处理正确的值。它在我尝试使用+=declare 构建名为$VAR_ID 的数组的部分失败。所以我自己的解决方案,或者我应该称之为解决方法,就是使用+=declare,但不能同时使用两者,因为那样会失败。
  • 这正是 nameref 应该提供帮助的地方。如果你在开头使用declare -n VAR_ID=my_arrayVAR_ID+=(whatever) 会将whatever 添加到名为my_array 的数组中,如果 bash 可以导出数组,export "${!VAR_ID}” 将导出my_array,但它不能。

标签: arrays bash variables export declare


【解决方案1】:

我不确定您到底想做什么,但您可以使用关联数组并将其导出。您可以使用 bash 中的变量访问关联数组的元素。

#!/usr/bin/env bash
declare -Ax arr # declare and export an associative array named 'arr'
declare -x var_id='array_position' # declare and export a variable named 'var_id'

for((i=0; i<=2; i++)); do
    val=${RANDOM}
    arr["${var_id}"]="${val}" # assign to the associative array with the var_id variable being the key, and val being the value
done

然后您可以使用变量、字符串或通过迭代访问关联数组。

# Using an exact key name
echo "${arr[array_position]}"
# Using a variable which points to the key name
echo "${arr[${var_id}]}"
# Using a for loop
for key in "${!arr[@]}"; do
    value="${arr[${key}]}"
    echo "${key} ${value}"
done

来自bash manpage

当分配给关联数组时,复合词中的单词 赋值可以是赋值语句,其中 下标是必需的,或被解释为 交替键和值的序列:name=(key1 value1 key2 value2 ……)。这些被视为与 name=( [key1]=value1 [key2]=value2 … )。列表中的第一个词决定了 剩余的单词被解释;列表中的所有分配必须是 同一类型。使用键/值对时,键可能不会丢失 或为空;最终缺失值被视为空字符串。

declare 内置函数也接受此语法。单个阵列 可以使用 name[subscript]=value 语法分配元素 上面介绍过。

【讨论】:

  • 这并没有解决我的问题,但没有仇恨,因为这对我来说很难解释。预计$VAR_ID(在上述特定情况下为my_array)是最后的数组,其中存储了所有$VALs(一些随机数,但可以是任何东西),而不是一些位置标识符在始终称为arr 或其他名称的数组中。但我自己提供了一个解决方案。不幸的是,我无法再将其发布为答案。
【解决方案2】:

对于遇到相同问题的任何人,以下是我自己的问题的答案:

#!/bin/bash

COUNT=0
VAR_ID="my_array"
declare PSEUDOARRAY    # is actually just a list of strings separated by spaces

while (( $COUNT <= 2 ))
do
    VAL=$RANDOM
    PSEUDOARRAY+="$VAL "
    (( COUNT++ ))
done

declare -agx $VAR_ID='( $PSEUDOARRAY )'    # "cast" PSEUDOARRAY on an actual array

这解决了我的问题。请注意,如果您最后不执行“演员”部分,而直接使用VAR_ID,则生成的my_array 不会提供诸如${my_array[0]} 之类的内容以仅提供第一项或${#my_array[@]} 以计数物品。

另请注意:此方法受到限制,因为它不区分分隔符空格和可能存储在VAL 中的“值空间”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-23
    • 1970-01-01
    • 2019-03-24
    • 2017-03-14
    • 2019-06-01
    相关资源
    最近更新 更多