检查 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
产生 HOSTNAME
和 HOSTTYPE
,例如。
相关的 ${!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 上的扩展正则表达式进行匹配,以确定它是否是一个感兴趣的名称。
我正在尝试读取 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
产生HOSTNAME
和HOSTTYPE
,例如。相关的
${!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 上的扩展正则表达式进行匹配,以确定它是否是一个感兴趣的名称。