2017-04-09 162 views
3

我想从Bash变量中读取我知道其名称后缀的变量,但我想遍历前缀。用动态名称检查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 

是否有任何与巴什做到这一点? 我已经尝试过eval和关联数组,但我仍然找不到一种方法来检查已定义的变量。

回答

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 
+0

谢谢!这正如我想要的那样工作! –

2

auhuman's helpful answer正是解决您的问题,问。

这里不需要你先指定一个数组名称前缀假设感兴趣的所有变量都具有相同前缀名称,如var替代,

for name in "${[email protected]}" # 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 
  • 代码使用形式击变量间接的,全部基于语法${!...}

    • "${[email protected]}"字面基于列表形式:它扩大到列表(阵列)的名的所有定义的变量,其名称有文字前缀var(他们的名字开始于var),如果有的话。由于只有一个文字被允许先@,使用模式,如
      "${!var[0-9][email protected]}"用于更复杂的匹配确实工作,很遗憾。

      • 实施例:for varName in "${[email protected]}"; do echo "$varName"; done
        产生HOSTNAMEHOSTTYPE,例如。

      • 相关的${!var*}语法(没有双引号)似乎工作相同。 (奇怪的是,man页面声称$IFS值的第一个字符用于连接匹配的名称,如果该第一个字符只在for循环中按预期方式工作,那么该值只能按预期工作。是一个空白字符。 ($IFS默认值为真,以空格开头),但实际上始终使用空间,与$IFS的值无关;与([email protected]; echo ${!HOST*})验证)

    • ${!name},所述可变为基础的标量形式,膨胀到其名称存储为$name的值的变量的值。

      • 例如:var='value'; name='var'; echo ${!name}得到value

      • 注:一招(上面使用),你可以用间接的方式得到阵列的价值观太,即通过附加的所有指数中索引表达式[@]到的名称可变间接引用;例如:
        arr=(one two three); name='arr[@]'; echo "${!name}" 收率one two three;访问一个特定的元素这种方式(例如,name='arr[1]')的工作原理也一样,但提取元件的范围确实(例如,name='arr[@]: 0:2')。

    • 还有一个阵列索引列表形式 - 上面未使用 - 其扩展到一个给定的阵列/关联数组的索引/密钥的列表(数组)。

      • 实施例:arr=(one two three); echo "${!arr[@]}"
        产生0 1 2,所述阵列的所述隐式连续索引。

      • 它与显式分配的索引的工作原理类似地(例如,
        arr=([10]=one two three); echo "${!arr[@]}"),或者在击V4 +,与缔合阵列(尽管,如关联数组的性质,键不能保证在顺序列出他们被定义;例如,
        declare -A aarr=([one]=1 [two]=2); echo "${!aarr[@]}")。

  • [[ $v =~ ^var[0-9]+_(name|size)$ ]]使用=~操作者的变量名称在手对阵上RHS上的扩展正则表达式以确定它是否是所关注的名称。

+1

我实际上不使用名称var1,var2 ...它有点不同,但它对于我在该脚本中做类似的事情可能非常有用,谢谢! –

+0

@OfriRips:理解,谢谢。我已经说得更清楚了,我的答案假定共享名称前缀(并且我添加了变量间接的概述)。感谢您回来并接受auhuman的回答。还请考虑重温您的旧问题,看看那里的答案是否应该被接受。 – mklement0