Dar*_*ert 5 arrays bash associative-array
使用 bash,可以将数组存储在字典中吗?我已经展示了一些从字典中获取数组的示例代码,但它似乎失去了它是一个数组的事实。
我希望这是dict+=(["pos"]="${array[@]}")命令,但不确定如何执行此操作或什至可能。
# Normal array behaviour (just an example)
array=(1 2 3)
for a in "${array[@]}"
do
echo "$a"
done
# Outputs:
# 1
# 2
# 3
# Array in a dictionary
declare -A dict
dict+=(["pos"]="${array[@]}")
# When I fetch the array, it is not an array anymore
posarray=("${dict[pos]}")
for a in "${posarray[@]}"
do
echo "$a"
done
# Outputs:
# 1 2 3
# but I want
# 1
# 2
# 3
Run Code Online (Sandbox Code Playgroud)
printf '%q '+eval您可以将数组展平为字符串:
printf -v array_str '%q ' "${array[@]}"
dict["pos"]=$array_str
Run Code Online (Sandbox Code Playgroud)
...然后使用eval该数组扩展回来:
# WARNING: Only safe if array was populated with eval-safe strings, as from printf %q
key=pos; dest=array
printf -v array_cmd "%q=( %s )" "$dest" "${dict[$key]}"
eval "$array_cmd"
Run Code Online (Sandbox Code Playgroud)
printf '%q '请注意,只有当您的关联数组是通过在添加值之前对值进行转义的代码填充的时,这才是安全的;避免此过程的内容可能对 不安全eval。
速度较慢但更安全(如果您无法防止不受信任的代码修改字典的内容),另一种方法是存储 Base64 编码的 NUL 分隔列表:
dict["pos"]=$(printf '%s\0' "${array[@]}" | openssl enc base64)
Run Code Online (Sandbox Code Playgroud)
...并以同样的方式读出:
array=( )
while IFS= read -r -d '' item; do
array+=( "$item" )
done < <(openssl enc -d base64 <<<"${dict["pos"]}"
Run Code Online (Sandbox Code Playgroud)
这个实际上是对称的,尽管它需要 bash 4.3 或更高版本。也就是说,它将您的键名称限制为允许作为 shell 变量名称的名称。
key=pos
array=( "first value" "second value" )
printf -v var_name 'dict_%q' "$key"
declare -n var="$var_name"
var=( "${array[@]}" )
unset -n var
Run Code Online (Sandbox Code Playgroud)
...此后declare -p dict_pos将发出declare -a dict_pos=([0]="first value" [1]="second value"). 在另一端,用于检索:
key=pos
printf -v var_name 'dict_%q' "$key"
declare -n var="$var_name"
array=( "${var[@]}" )
unset -n var
Run Code Online (Sandbox Code Playgroud)
...此后declare -p array将发出declare -a array=([0]="first value" [1]="second value").