使用动态名称检查Bash变量

时间:2017-04-09 12:51:47

标签: bash variables eval associative-array variable-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和关联数组,但我仍然找不到检查已定义变量的方法。

2 个答案:

答案 0 :(得分:3)

以下对我有用。您需要先构造变量,然后使用感叹号对其进行评估。

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

答案 1 :(得分:2)

auhuman's helpful answer完全按照要求解决您的问题。

这是一个替代方案,它不要求您首先在数组中指定名称前缀,假设所有感兴趣的变量都具有相同前缀的名称,例如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@}" 文字列表表格:它会扩展为列表(数组)所有已定义变量的名称,其名称具有 literal 前缀var(其名称​​以 {{开头) 1}}),如果有的话。由于只允许文字在var之前,使用诸如
      的模式 不幸的是, @ 用于更复杂的匹配工作。

      • 示例:"${!var[0-9]_@}"
        例如,收益率for varName in "${!HOST@}"; do echo "$varName"; doneHOSTNAME

      • 相关的HOSTTYPE语法(不带双引号)似乎工作原理相同。
        (奇怪的是,${!var*}页面声称man值的第一个字符用于连接匹配的名称,如果第一个字符只能在$IFS循环中按预期工作。是一个空白字符。(for默认值,以空格开头),但实际上总是使用空格,不论$IFS的价值如何;请与$IFS确认

    • (IFS=@; echo ${!HOST*}) 变量 - 基于标量形式,扩展为 name 存储为${!name}的值。

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

      • 注意:通过一个技巧(上面没有 ),您可以使用间接来获取数组的值 ,即通过将all-indices索引表达式value附加到要间接引用的变量名称;例如: -
        [@] 收益率arr=( one two three ); name='arr[@]'; echo "${!name}";以这种方式访问​​特定元素(例如,one two three)也可以,但提取元素的范围 (例如, {{1} } )。

    • 上面还有一个 阵列索引 列表表单 - - 扩展了到给定数组/关联数组的索引/键的列表(数组)。

      • 示例:name='arr[1]'
        产生name='arr[@]: 0:2',数组的隐式顺序索引。

      • 它与明确指定的指数类似地工作(例如,
        {B} v4 +中的arr=( one two three ); echo "${!arr[@]}")或关联数组(尽管关联数组的性质也是如此,但不保证按照定义的顺序列出键;例如, 0 1 2)。

  • arr=( [10]=one two three ); echo "${!arr[@]}"使用declare -A aarr=( [one]=1 [two]=2 ); echo "${!aarr[@]}"运算符将手头的变量名称与RHS上的扩展正则表达式进行匹配,以确定它是否是感兴趣的名称。