我想将bash中的关联数组转换为JSON散列/dict。我更喜欢使用JQ来完成此操作,因为它已经是一个依赖项,我可以依赖它来生成格式良好的json。有人能演示如何实现此操作吗?
#!/bin/bash
declare -A dict=()
dict["foo"]=1
dict["bar"]=2
dict["baz"]=3
for i in "${!dict[@]}"
do
echo "key : $i"
echo "value: ${dict[$i]}"
done
echo 'desired output using jq: { "foo": 1, "bar": 2, "baz": 3 }'
5条答案
按热度按时间hmmo2u0o1#
有很多种可能性,但是考虑到您已经编写了一个bash
for
循环,您可能希望从脚本的以下变体开始:结果反映了bash
for
循环生成的密钥的顺序:一般来说,基于给jq提供键值对的方法,其中一个键在一行上,对应的值在下一行上,有很多值得推荐的地方。下面给出了遵循这种通用方案的通用解决方案,但使用NUL作为“行结束”字符。
作为JSON实体的键和值
为了使上面的代码更通用,最好将键和值表示为JSON实体。在本例中,我们可以编写:
其他变更
JSON键必须是JSON字符串,因此可能需要做一些工作来确保实现从bash键到JSON键的Map。类似的注解也适用于从bash数组值到JSON值的Map。处理任意bash键的一种方法是让jq进行转换:
当然,您可以对bash数组值执行相同的操作,并让jq检查该值是否可以根据需要转换为数字或其他JSON类型(例如,使用
fromjson? // .
)。通用解决方案
下面是一个通用的解决方案沿着于jq FAQ中提到的方法,由@CharlesDuffy提出。它在将bash键和值传递给jq时使用NUL作为分隔符,并且具有只需要一次调用jq的优点。如果需要,可以省略过滤器
fromjson? // .
或用另一个过滤器替换。输出:
h5qlskok2#
此答案来自
freenode
#jq
上的nico103
:nbnkbykc3#
你可以将一个变量初始化为一个空对象
{}
,并为每次迭代添加键/值{($key):$value}
,将结果重新注入同一个变量:pu3pd22g4#
这已经被贴出来了,并记入了IRC上的nico 103,也就是说,我。
很自然地,让我感到害怕的是这些关联数组的键和值需要引号,下面是一个开始,需要一些额外的工作来对键和值进行反引号操作:
所以现在所需要的就是一个jq函数,它可以删除引号,引号有几种类型:
我把这最后一项留给读者作练习。
我应该注意,我在这里使用
printf
作为迭代器!3bygqnnd5#
bash 5.2引入了
@k
parameter transformation,使这一点变得更加容易。例如: