我想使用jq
递归转换任意JSON文件:
输入
{
"id": 123456,
"name": "Test",
"more": [1, 2, 3],
"instance": {
"id": 987654,
"name": "Different"
}
}
输出
[
{
"name" : "id",
"type": "number",
"value": 123456
},
{
"name": "name",
"type": "string",
"value": "Test"
},
{
"name":"more",
"type": "array",
"value": [1, 2, 3]
},
{
"name": "instance",
"type": "object",
"value": [
{
"name": "id",
"type": "number",
"value": 987654
},
{
"name": "name",
"type": "string",
"value": "Different"
}
]
}
]
转换说明
每个键值对都应该转换为一个包含键name, type, value
的对象。而name
应该是原始的 key。type
应该是jq的type
运算符感知到的原始值的 type。由于键值对被转换为复杂对象,因此同一层次结构上的键值对成为同一数组的一部分。
这可以通过jq
实现吗?
1条答案
按热度按时间sz81bmfz1#
您的需求几乎符合
to_entries
正在做的事情。但是你需要在一个自顶向下的递归中向下传递类型(因为使用自底向上的方法,比如usingwalk
,在之后确定类型时,预先被to_entries
转换为数组的对象变得与正确的数组无法区分)。因此,递归函数可以设置类型和值,如果值是一个对象,使用to_entries
并在递归结果前添加名称:Demo
关于你的评论数组应该“保持不变”的注解:虽然这澄清了数组不应该被转换(例如,使用数字索引作为它们的项的“名称”),仍然不清楚是否希望再次作为对象本身的数组项也被转换(同时留在未转换的数组中)。例如,将示例中的
[1, 2, 3]
更改为[1, {"x":2}, 3]
。上面假设这个数组应该按原样复制(Demo)。然而,如果你想把递归也向下传播到数组项中,也要更新数组(在对象之前,不要遇到自底向上的问题),例如。使用arrays |= map(f.value) | objects |= …
(Demo),对于改变的示例,这将产生[1, [{"name": "x", "type": "number", "value": 2}], 3]
。