我有一些bash代码,可以使用jq对bash中的一维关联数组进行序列化和反序列化。它可以满足我目前的需求,但是有两个问题。
第一个问题是,这段代码实在太笨拙了。特别是序列化部分。有一个更好的方法吗?用jq还是其他方式?
第二个问题是,我可以反序列化嵌套数据(例如,使用{"data":{...}}
),但是我不知道如何将输出包装在相同的嵌套结构中。如何重新创建原始结构?
编辑:澄清。我想做的是,在示例代码中加上注释的json,json='{"data": {"one": "1", "two": "2", "three": "3"}}'
,并丢弃
json='{"data": {"four": "4", "one": "100", "two": "2"}}
的最终结果。
我可以读取“数据”结构并正确分配键/值,但是我对确定如何将{"four": ...}
构造嵌入到"data": {...}
对象中没有任何运气。
编辑2:结合第二个问题,我的第二个问题的答案如下:
for key in "${!aaname[@]}"; do
printf '%s\n%s\n' "$key" "${aaname[$key]}"
done | jq -SRn '.data = ([inputs | {(.): input}] | add)'
代码是:
#!/bin/bash
#json='{"data": {"one": "1", "two": "2", "three": "3"}}'
json='{"one": "1", "two": "2", "three": "3"}'
#------------------------------------------------------------------------------
# De-serialize data
declare -A aaname
while IFS='=' read -r key value; do
aaname["$key"]="$value"
done < <(echo "$json" | jq -r '. | to_entries | .[] | .key + "=" + .value ')
#done < <(echo "$json" | jq -r '.data | to_entries | .[] | .key + "=" + .value ')
#------------------------------------------------------------------------------
# Manipulate data
# Change existing value ...
aaname['one']='100'
# Add element ...
aaname['four']='4'
# Remove element ...
unset aaname['three']
#------------------------------------------------------------------------------
# Serialize data
# Why can't I use ${#aaname[@]} in ((...))?
total="${#aaname[@]}"
count=0
{
printf '['
for key in "${!aaname[@]}"; do
printf '{"key": "%s", "value": "%s"}' "$key" "${aaname[$key]}"
((++count < total)) && printf ','
done
printf ']'
#}
#} | jq -S ' . | "data{" + from_entries + "}"'
} | jq -S ' . | from_entries'
# gives
#
#{
# "four": "4",
# "one": "100",
# "two": "2"
#}
答案 0 :(得分:1)
如果不是这样的话,它会不太笨拙,也许会更健壮
jq -r '. | to_entries | .[] | .key + "=" + .value ')
您有:
jq -r 'to_entries[] | "\(.key)=\(.value)"'
类似地,您可以使用类似以下的内容替换用于创建JSON对象的for
循环:
for key in "${!aaname[@]}"; do
printf "%s\n" "$key"
printf "%s\n" "${aaname[$key]}"
done | jq -Rn '[inputs | { (.): input}] | add'
关于第二个问题,恐怕您对我的问题不太清楚。
您希望非JSON表示采用什么格式?
您期望序列化/反序列化解决方案的通用性如何?
在这方面,您可能想看看jq --stream . <<< "$json"
的输出
各种JSON文本。