检查 Bash 个具有动态名称的变量

Examine Bash variables with dynamic names

我正在尝试读取 Bash 个我知道名称后缀的变量,但我想遍历前缀。

下面我举个例子:

var1_name="variable1"
var1_size="2"
var2_name="variable2"
var2_size="3"
vars=(var1 var2)

for v in "${vars[@]}"
do
    echo $v_name
    echo $v_size
done

我希望输出如下所示:

variable1
2
variable2
3

Bash有什么办法吗? 我已经尝试使用 eval 和关联数组,但我仍然找不到检查已定义变量的方法。

以下适合我。您需要先构造变量,然后使用感叹号对其求值。

var1_name="variable1"
var1_size="2"
var2_name="variable2"
var2_size="3"
vars=("var1" "var2")

for v in "${vars[@]}"
do
    name=${v}_name
    size=${v}_size
    echo ${!name}
    echo ${!size}
done

O/P

variable1
2
variable2
3

完全按照您的要求解决了您的问题。

这里有一个替代方案,它不需要您先在数组中指定名称前缀,假设所有感兴趣的变量的名称都具有相同的前缀,例如var:

for name in "${!var@}"  # Loop over all variables whose names start with 'var'.
do
    [[ $name =~ ^var[0-9]+_(name|size)$ ]] || continue # Ignore unrelated names.
    echo "${!name}" # Use variable indirection to print the variable's value. 
done
  • 代码使用两种形式的Bash变量间接,全部基于语法${!...}:

    • "${!var@}" 是基于文字列表形式: 它扩展到 list (array) of the names 所有已定义变量的名称 literal[=122] =] 前缀 var(其名称 var 开头),如果有的话。由于只允许在 @ 之前使用文字,因此使用
      这样的模式 不幸的是,"${!var[0-9]_@}" 对于更复杂的匹配 没有 工作。

      • 示例:for varName in "${!HOST@}"; do echo "$varName"; done
        产生 HOSTNAMEHOSTTYPE,例如。

      • 相关的 ${!var*} 语法(没有 双引号)似乎工作相同。
        (奇怪的是,man 页面声称 $IFS 值的第一个字符用于连接匹配的名称,如果第一个字符,这只会在 for 循环中按预期工作. 是一个 whitespace 字符($IFS 默认值也是如此,它以 space 开头),但实际上是一个space总是被使用,不管$IFS的值如何;用(IFS=@; echo ${!HOST*})验证

    • ${!name},基于变量标量形式,扩展为变量的值,其 name 存储为 $name.

      的值
      • 示例:var='value'; name='var'; echo ${!name} 产生 value

      • 注意:使用一个技巧(不是上面使用的),你可以使用间接得到一个数组的值也,即在变量名后附加全索引表达式[@]间接引用;例如:
        arr=( one two three ); name='arr[@]'; echo "${!name}" 产量 one two three;以这种方式访问​​特定元素(例如,name='arr[1]')也有效,但提取元素的 范围 确实 not(例如,name='arr[@]: 0:2').

    • 还有一个array-index list形式 -上面使用的 not - 它扩展到给定数组/关联数组的索引/键的列表(数组)。

      • 示例:arr=( one two three ); echo "${!arr[@]}"
        产生 0 1 2,数组的隐式顺序索引。

      • 它与显式分配的索引类似(例如,
        arr=( [10]=one two three ); echo "${!arr[@]}") 或者,在 Bash v4+ 中,使用关联数组(虽然,正如关联数组的性质一样,不能保证键按照定义的顺序列出;例如,
        declare -A aarr=( [one]=1 [two]=2 ); echo "${!aarr[@]}").

  • [[ $v =~ ^var[0-9]+_(name|size)$ ]] 使用 =~ 运算符将手头的变量名与 RHS 上的扩展正则表达式进行匹配,以确定它是否是一个感兴趣的名称。