我有环境变量,其中包含 JSON 文本。我想用jq
工具向其中添加一些数据。我想保留所有旧字段,但添加和/或覆盖新字段。这个想法与向变量添加路径相同PATH
,但是使用JSON
.
即使我不明白,如何制作和示例。对于我写的一个值
echo "{\"A\":\"Hello world\"}" | jq -r
现在假设我想将此对象与另一个对象合并
echo "{\"A\":\"Goodbye world\", \"B\": \"This was a joke\"}"
答案1
您的示例很奇怪,因为新值将完全替换旧值。原始值只有一个键“A”,要“合并”的值包含键“A”的不同值,该值将替换原始值。
因此,为了便于说明,我将假装您的意思是这些输入按其他顺序排列(以便“Hello world”将覆盖“Goodbye world”,而“这是一个笑话”将保持不变)。
可以这样做:
( echo "{\"A\":\"Goodbye world\", \"B\": \"This was a joke\"}" ; echo "{\"A\":\"Hello world\"}" ) | jq -s add
关键在于您只是按顺序输入两个 json 对象,因此您可以-s
将jq
它们视为在数组中;然后你只需将它们传递给add
过滤器,过滤器将数组的所有元素添加在一起。
当在 中添加对象时jq
,它们会被合并,任何相同的键都会被解析为有利于加法操作右侧的对象(在本例中为两个对象中的后者)。
请参阅文档:
答案2
您可以使用 shell 技巧和进程替换来将 JSON 字符串作为输入文件输入jq
,然后将两个文件的内容连接起来
jq -s '.[0] + .[1]' \
<(echo "{\"A\":\"Goodbye world\", \"B\": \"This was a joke\"}") \
<(echo "{\"A\":\"Hello world\"}")
由于A
是两个对象之间的公共键,因此在最终结果中将其替换
{
"A": "Hello world",
"B": "This was a joke"
}
或者您可以使用输入功能
printf '%s\n%s\n' "{\"A\":\"Goodbye world\", \"B\": \"This was a joke\"}" \
"{\"A\":\"Hello world\"}" | \
jq '.+= input'
功能input
用于:
input
和输入[...]从与jq本身相同的源(例如,stdin、在命令行上命名的文件)读取。这两个内置函数以及 jq 自己的读取操作可以相互交错