使用 readarray 将 json 字典转换为 bash 哈希表
首先是一个数组的工作示例
json_array() {
local -n array="${1}"
readarray -d $'\0' -t array < <(
# Create nul delimited array entry using jq
jq -cjn --argjson arr "$array" '$arr|map(tostring)|.[]+"\u0000"'
)
}
> unset arr; arr='["a", "b", "c"]'; json_array arr; echo "${arr[0]} ${arr[1]} ${arr[2]}"
a b c
现在我尝试用 dict 做类似的事情,将 json dict 转换为 bash 关联数组
json_dict() {
local -n dict="${1}"
declare -A hash_table
append_to_hash_table() {
shift
{ read -r key; read -r value; } <<<"$1"
hash_table+=([$key]="$value")
}
readarray -d $'\0' -c 1 -C append_to_hash_table < <(
# Create nul delimited dict entry using jq
jq -cjn --argjson d "$dict" '$d|to_entries|map("\(.key)\n\(.value|tostring|@sh)")|.[]+"\u0000"'
)
# Here hash_table contain the correct output
dict=""
dict="$hash_table"
}
> unset arr; arr='{"a": "aa", "l": "bb", "c": "ccccc"}'; json_dict arr; echo "${arr[@]}"
Nothing
似乎 dict="$hash_table" 没有正确更新引用名称, 如何使 bash dict
refname 指向 hash_table
?
First a working example with arrays
json_array() {
local -n array="${1}"
readarray -d
Now I'm trying to do something similar with dict, convert a json dict into a bash associative array
json_dict() {
local -n dict="${1}"
declare -A hash_table
append_to_hash_table() {
shift
{ read -r key; read -r value; } <<<"$1"
hash_table+=([$key]="$value")
}
readarray -d
It seems dict="$hash_table"
doesn't correctly update the refname,
How can I make bash dict
refname point to hash_table
?
\0' -t array < <(
# Create nul delimited array entry using jq
jq -cjn --argjson arr "$array" '$arr|map(tostring)|.[]+"\u0000"'
)
}
> unset arr; arr='["a", "b", "c"]'; json_array arr; echo "${arr[0]} ${arr[1]} ${arr[2]}"
a b c
Now I'm trying to do something similar with dict, convert a json dict into a bash associative array
It seems dict="$hash_table"
doesn't correctly update the refname,
How can I make bash dict
refname point to hash_table
?
\0' -c 1 -C append_to_hash_table < <(
# Create nul delimited dict entry using jq
jq -cjn --argjson d "$dict" '$d|to_entries|map("\(.key)\n\(.value|tostring|@sh)")|.[]+"\u0000"'
)
# Here hash_table contain the correct output
dict=""
dict="$hash_table"
}
> unset arr; arr='{"a": "aa", "l": "bb", "c": "ccccc"}'; json_dict arr; echo "${arr[@]}"
Nothing
It seems dict="$hash_table"
doesn't correctly update the refname,
How can I make bash dict
refname point to hash_table
?
Now I'm trying to do something similar with dict, convert a json dict into a bash associative array
It seems dict="$hash_table"
doesn't correctly update the refname,
How can I make bash dict
refname point to hash_table
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这里不需要
readarray
:您可以将两个单独的 NUL 分隔的read
作为while
循环的一部分。请参阅 https://replit.com/@CharlesDuffy2/GrandioseDraftyArguments#main 演示的以下答案。 sh
将其放入上下文中:
...作为输出发出:
也就是说,要完全按照要求回答问题,因此使用readarray:
There's no need for
readarray
here: You can have two separate NUL-delimitedread
s as part of yourwhile
loop.See the below answer demonstrated at https://replit.com/@CharlesDuffy2/GrandioseDraftyArguments#main.sh
Putting this into context:
...emits as output:
That said, to answer the question exactly as-asked, thus using
readarray
:仅使用
declare
并让jq
使用@sh
创建内容以实现 shell 一致性不是更简单吗?索引数组:
关联数组:
响应编辑请求: 上面要求值是字符串(数字和布尔值也可以),但其他结构需要首先转换为字符串格式。特别是,在请求之后,
@json
可用于将任意 JSON 内容编码为字符串。但是,请记住,这样做时,bash 数组的项目将进行 JSON 编码,这意味着简单的情况(上面的aa
之类的字符串)也将被编码(例如“aa”
,包括引号,按照 JSON 的要求)。如果这是您想要的,请尝试:具有 JSON 编码值的索引数组:
具有 JSON 编码值的关联数组:
Wouldn't it be simpler to just use
declare
and havejq
create the contents using@sh
for shell conformity?Indexed array:
Associative array:
Reacting to an edit request: The above requires the values to be strings (numbers and booleans will kind of work, too), but other structures need to be brought into a stringy format first. In particular, following the request,
@json
could be used to encode an arbitrary JSON content as a string. However, keep in mind that in doing so, the bash array's items will be JSON-encoded, which means that also the simple cases (strings likeaa
from above) will be encoded (e.g. as"aa"
, including the quotes, as required by JSON). If this is what you want, go for it:Indexed array with JSON-encoded values:
Associative array with JSON-encoded values: