我正在玩一个用于学习目的的非感性脚本(只写一些变量范围处理的例子)。我定义了几个这样的变量:
sb_var_global=TRUE
typeset sb_var_typeset=TRUE
typeset -g sb_var_typeset_g=TRUE
declare sb_var_declare=TRUE
declare -g sb_var_declare_g=TRUE
export sb_var_export=TRUE
typeset -gx sb_var_typeset_gx=TRUE
declare -gx sb_var_declare_g=TRUE
然后我按照这样显示它们:
echo "Set variables ..."
set | grep sb_var_
echo "\n Environment variables ..."
env | grep sb_var_
这会生成如下输出:
Displaying *set* variables ...
sb_var_declare=TRUE
sb_var_declare_g=TRUE
sb_var_export=TRUE
sb_var_func_declare_g=TRUE
sb_var_func_global=TRUE
sb_var_func_typeset_g=TRUE
sb_var_global=TRUE
sb_var_readonly=TRUE
sb_var_typeset=TRUE
sb_var_typeset_g=TRUE
sb_var_typeset_gx=TRUE
Displaying *env* variables ...
sb_var_export=TRUE
sb_var_typeset_gx=TRUE
sb_var_declare_g=TRUE
我开始尝试将该输出作为关联数组进行处理,但我无法正确理解语法。
这循环遍历每一行,然后针对每一行(单独)执行字符串扩展,将每行分成一个数组(不是我想要的):
for var in $(set | grep sb_var_); do
tokens=(${(s:=:)var})
print ${tokens[1]} ${tokens[2]}
done
处理关联数组的标准方法是:
for key val in ${(kv)assoc_array}; do
echo "$key -> $val"
done
要使用这种类型的语法,我需要执行命令替换,在返回时拆分每一行,并将结果存储在直接传递给for循环结构的关联数组中。我认为这可能看起来像:
for key val in ${(kv)${(s:=:)$(set | grep sb_var_)}}; do
echo "$key -> $val"
done
虽然这不太正确,最终会产生如下输出:
sb_var_declare -> TRUE sb_var_declare_g
TRUE sb_var_export -> TRUE sb_var_func_declare_g
TRUE sb_var_func_global -> TRUE sb_var_func_typeset_g
TRUE sb_var_global -> TRUE sb_var_readonly
TRUE sb_var_typeset -> TRUE sb_var_typeset_g
TRUE sb_var_typeset_gx -> TRUE
尝试将其拆分以使其更易于管理,我无法弄清楚如何使语法正确,我最好的尝试就是这样(语法无效):
declare -A values=${(s:=:)$(set | grep sb_var_)}
有什么建议吗?
答案 0 :(得分:0)
您缺少的是告诉您要定义的数组,将新行视为分隔符,而不是设置为$IFS
的内容。您应该可以通过添加标志来将它们视为数组(@
),将原始结果与换行符(F
)连接起来,然后在主循环中将输出拆分为换行符( F
)。
示例:
# Notice the new @f and @F flags
for key val in ${(@fkv)${(@Fs:=:)$(set | grep sb_var_)}}; do
echo "$key -> $val"
done