我正在尝试读取我知道名称后缀的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
和关联数组,但我仍然找不到检查已定义变量的方法。
答案 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"; done
和HOSTNAME
。
相关的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上的扩展正则表达式进行匹配,以确定它是否是感兴趣的名称。