迭代bash中作为键/值对中的值嵌入的列表
我试图在bash中获得一个(键、多值)结构(某种hashmap),如下所示:迭代bash中作为键/值对中的值嵌入的列表,bash,dictionary,Bash,Dictionary,我试图在bash中获得一个(键、多值)结构(某种hashmap),如下所示: [ [ "abc" : 1, 2, 3, 4 ], [ "def" : "w", 33, 2 ] ] for key in ${map[@]} do; echo $key # "abc" then "def" for value in ${map[$key,@]} do; ... done done 我希望遍历每个键(某种类型的用于输入…,并使用map[“def”,2]或m
[
[ "abc" : 1, 2, 3, 4 ],
[ "def" : "w", 33, 2 ]
]
for key in ${map[@]} do;
echo $key # "abc" then "def"
for value in ${map[$key,@]} do;
...
done
done
我希望遍历每个键(某种类型的用于输入…
,并使用map[“def”,2]
或map[$key,2]
之类的内容获取每个值
我已经看到几个线程讨论了单值hashmap,但没有讨论这个问题
我可以使用N
数组,N
是我的映射中的键的数量,用一行中的每个字段填充,但我不想尽可能多地重复代码
提前谢谢
编辑:
我想用这样的东西来介绍一下结构:
[
[ "abc" : 1, 2, 3, 4 ],
[ "def" : "w", 33, 2 ]
]
for key in ${map[@]} do;
echo $key # "abc" then "def"
for value in ${map[$key,@]} do;
...
done
done
这个宣言有点难看
declare -A map=(
[abc,0]=1
[abc,1]=2
[abc,2]=3
[abc,3]=4
[def,0]=w
[def,1]=33
[def,2]=2
)
key="def"
i=1
echo "${map[$key,$i]}" # => 33
迭代:有助于保留单独的“键”数组: 然后
这个宣言有点难看
declare -A map=(
[abc,0]=1
[abc,1]=2
[abc,2]=3
[abc,3]=4
[def,0]=w
[def,1]=33
[def,2]=2
)
key="def"
i=1
echo "${map[$key,$i]}" # => 33
迭代:有助于保留单独的“键”数组: 然后
将现代bash功能与多阵列案例结合使用:
作业(手册): 分配(方案性): 迭代(在函数内完成以包含namevar的作用域):
这也可以在没有命名变量的情况下完成,但会以更丑陋、更容易出错的方式完成(要清楚,我相信这里给出的代码安全地使用了
eval
,但很容易出错——如果试图在此模板上构建自己的实现,请非常小心)
…并且,要以与bash兼容的方式通过3.x进行迭代:
for array in ${!map_@}; do
echo "Iterating over array ${array#map_}"
printf -v cur_array_cmd 'cur_array=( ${%q[@]} )' "$array"
eval "$cur_array_cmd"
for key in "${!cur_array[@]}"; do
echo "$key: ${cur_array[$key]}"
done
done
这比通过单个大数组进行过滤(给出了另一个答案)在计算效率上更高,而且,当namevar可用时,可以说还会产生更干净的代码。将现代bash功能用于多数组情况:
作业(手册): 分配(方案性): 迭代(在函数内完成以包含namevar的作用域):
这也可以在没有命名变量的情况下完成,但会以更丑陋、更容易出错的方式完成(要清楚,我相信这里给出的代码安全地使用了
eval
,但很容易出错——如果试图在此模板上构建自己的实现,请非常小心)
…并且,要以与bash兼容的方式通过3.x进行迭代:
for array in ${!map_@}; do
echo "Iterating over array ${array#map_}"
printf -v cur_array_cmd 'cur_array=( ${%q[@]} )' "$array"
eval "$cur_array_cmd"
for key in "${!cur_array[@]}"; do
echo "$key: ${cur_array[$key]}"
done
done
这比通过单个大数组进行过滤(给出的另一个答案)在计算效率上更高,而且,当namevar可用时,可以说也会产生更干净的代码。有什么原因需要使用bash吗?它确实不太适合这样做。是的,我知道,但我真的需要bash:)可能是重复的好吧,它不是那么优雅(我没想到解决方案会是这样)。我试试看!哪个版本的bash?如果是4.3或更高版本,则可以使用namevar,这使得多数组实现更易于处理。是否有理由使用bash?它真的不太适合这个。是的,我知道,但我真的需要在这一点上重击:)可能重复的好,它不是那么优雅(我没想到的解决方案是)。我试试看!哪个版本的bash?如果是4.3或更高版本,则可以使用名称变量,这使得多数组实现更易于处理。谢谢,但请参见上面的编辑!迭代${map[@]}(使用单个循环)将输出每个值。已更新。不幸的是,复杂的bash数据结构意味着复杂的代码谢谢,但是请参见我上面的编辑!迭代${map[@]}(使用单个循环)将输出每个值。已更新。不幸的是,复杂的bash数据结构意味着复杂的编解码器、完整的答案、漂亮的帖子和漂亮的解释。你应该得到1000谢谢!非常感谢。完整的答案,漂亮的帖子,漂亮的解释。你应该得到1000谢谢!非常感谢。
iter() {
for array in ${!map_@}; do
echo "Iterating over array ${array#map_}"
declare -n cur_array="$array" # BASH 4.3 FEATURE
for key in "${!cur_array[@]}"; do
echo "$key: ${cur_array[$key]}"
done
done
}
iter
# Compatible with older bash (should be through 3.x).
append() {
local array_name="${1}_$2"; shift; shift
declare -g -a "$array_name"
local args_str cmd_str
printf -v args_str '%q ' "$@"
printf -v cmd_str "%q+=( %s )" "$array_name" "$args_str"
eval "$cmd_str"
}
for array in ${!map_@}; do
echo "Iterating over array ${array#map_}"
printf -v cur_array_cmd 'cur_array=( ${%q[@]} )' "$array"
eval "$cur_array_cmd"
for key in "${!cur_array[@]}"; do
echo "$key: ${cur_array[$key]}"
done
done