![使用 jq 在特定行之前附加 json 块](https://linux22.com/image/201092/%E4%BD%BF%E7%94%A8%20jq%20%E5%9C%A8%E7%89%B9%E5%AE%9A%E8%A1%8C%E4%B9%8B%E5%89%8D%E9%99%84%E5%8A%A0%20json%20%E5%9D%97.png)
我有一个场景,我已经有一个 json 文件,我想使用 jq 打开和编辑该文件。
json 文件(temp.json):
{
"a":{
"keya" : "abc",
"keyb" : "xyz"
},
"c":{
"keyc" : "yyy"
}
}
在这里,我想c
通过搜索在块之前附加另一个 json 对象,基本上是在最后一个对象之前附加值,在这种情况下,最后一个对象将始终是c
"b":{
"keyb" : "yop"
}
我使用 jq 实现了插入块,但没有插入到所需的位置。
jq '. |= . + {"b":{ "keyb" : "yop" }}' temp.json
任何帮助都会很好
答案1
您可以使用jq
的-S
选项对键进行排序。例如
$ jq -S '. |= . + {"b":{ "keyb" : "yop" }}' temp.json
{
"a": {
"keya": "abc",
"keyb": "xyz"
},
"b": {
"keyb": "yop"
},
"c": {
"keyc": "yyy"
}
}
答案2
对象是未排序的键集合。键的顺序真的应该没关系到读取 JSON 文档的应用程序。如果您想要有序数据,请考虑使用数组。
以下是分步解决方案。最终代码在最后。
由于数组是有序的,我们可以使用以下方法将顶级对象转换为键和值的有序数组to_entries
:
$ jq 'to_entries' file
[
{
"key": "a",
"value": {
"keya": "abc",
"keyb": "xyz"
}
},
{
"key": "c",
"value": {
"keyc": "yyy"
}
}
]
我们可以在该数组的最后一个元素之前插入内容。在这里,我使用第一个元素(除了最后一个原始元素之外的所有元素.[:-1]
)、新元素以及最后一个原始元素(.[-1]
)的切片来重写“条目”数组。
$ jq 'to_entries | . |= .[:-1] + [ { key: "b", value: { keyb: "yop" } }, .[-1] ]' file
[
{
"key": "a",
"value": {
"keya": "abc",
"keyb": "xyz"
}
},
{
"key": "b",
"value": {
"keyb": "yop"
}
},
{
"key": "c",
"value": {
"keyc": "yyy"
}
}
]
然后我们可以将其转换回其原始形式,希望from_entries
不会改变键的顺序:
$ jq 'to_entries | . |= .[:-1] + [ { key: "b", value: { keyb: "yop" } }, .[-1] ] | from_entries' file
{
"a": {
"keya": "abc",
"keyb": "xyz"
},
"b": {
"keyb": "yop"
},
"c": {
"keyc": "yyy"
}
}
在命令行上将新元素作为键和 JSON 对象:
$ jq --arg key 'yellow' --argjson value '{ "type": "color" }' 'to_entries | . |= .[:-1] + [ { key: $key, value: $value }, .[-1] ] | from_entries' file
{
"a": {
"keya": "abc",
"keyb": "xyz"
},
"yellow": {
"type": "color"
},
"c": {
"keyc": "yyy"
}
}