Json 标记jq如何将多个路径组合到一个对象中
我有一个对象,我可以过滤到几个我希望保留的路径。路径的形式如下:Json 标记jq如何将多个路径组合到一个对象中,json,object,filtering,jq,Json,Object,Filtering,Jq,我有一个对象,我可以过滤到几个我希望保留的路径。路径的形式如下: [ "key1", "key2", "mykey" ] [ "key3", "key4", "mykey" ] 我想要的是: { "key1":{ "key2": .key2 }, "key3":{ "key4": .key4 } } 我能得到的最接近的结果是: { "key1":{ "key2": .key2 } } { "k
[
"key1",
"key2",
"mykey"
]
[
"key3",
"key4",
"mykey"
]
我想要的是:
{ "key1":{
"key2": .key2
},
"key3":{
"key4": .key4
}
}
我能得到的最接近的结果是:
{ "key1":{
"key2": .key2
}
}
{ "key3":{
"key4": .key4
}
使用:
(paths(objects)|select(last(.[])=="mykey")) as $path|
getpath([$path[0],$path[1]]) as $getpath|
{($path[0]):{($path[1]):$getpath}}
虽然我可以通过管道将此输出传输到jq-s'.'命令,但我找不到一种方法将原始过滤器集中的路径重建相加。过滤器似乎在每个对象的末尾重置$path看起来一次只保存一个路径数组,而不是一个路径数组。这防止我在reduce函数中迭代$path
我已经创建了下面的脚本,但我对如何使用path()函数感兴趣。到目前为止,我还没有弄明白如何使它对我非常有用
(to_entries |
map(select(.["value"][]?|has("mykey")?))|[.[].key]) as $rooms|
(to_entries |
map(select(.["value"][]?|has("mykey")?))|[.[].value]) as $roomvals| #allows room paths to be avail
##### creates object containing only those locations and sensors within the locations that include "mykey" objs
reduce
range(0;$rooms|length) as $i ({};
.+{($rooms[$i]): ($roomvals[$i] | to_entries |
map(select(.["value"]|has("mykey")))|{(.[]["key"]):.[]["value"]})})
感谢您对这些方法的任何帮助或其他方法的建议。您表示想要的输出不是JSON,我也不清楚想要的输出是什么,但以下内容似乎很接近:
reduce inputs as $d (null; setpath( $d[0: ($d|length) - 1]; $d[-1] ) )
通过您的输入,并使用jq-n,这将产生:
{
"key1": {
"key2": "mykey"
},
"key3": {
"key4": "mykey"
}
}
希望你能从这里开始
例子:
调用:jq-n-c-f example.jq
输出:
{"key1":{"key2":{"mykey":{"a":123}}},
"key3":{"key4":{"mykey":{"b":234}}}}
在peak回答的指导下,我现在可以更好地摆姿势回答我的问题 我已经扩展了peak在其示例中使用的数据对象,因此它更好地代表了我试图解决的问题。现在数据更好地说明了“键2”和“键10”有“mykey”,而“键6”、“键8”和“键11”没有。我想在我的问题中表达的是,我想保留“key2”和“key10”的完整路径,其中包括“另一个”和“我的键”。我意识到对peak的示例选择标准进行一个小小的修改就可以做到这一点。我只需要在选择中添加一个过滤器,以保留包含“mykey”的每个路径的前两个元素: 返回我想要的:
{"key1":{"key2":{"mykey":{"a":123},
"another":{"q":"six"}}},
"key3":{"key6":{"mykey":{"d":997},
"another":{"q":"seven"}}}
}
您将注意到选择现在包括“|[0:2]”
感谢peak将我的工作安排在正确的轨道上。我投票支持他的答案,因为它帮助我更好地表达我的问题,并让我有解决问题的洞察力。作为JSON新手,我可能没有选择正确的方式来说明我想要什么。主要对象“key1”和“key3”都有子对象,而子对象又有一个“mykey”。没有说明的是,“mykey”只是对象“key2”和“key4”的几个子对象之一。{“key2”:.key2}可能最好用另一种方式表示,比如说
{“key2”:getpath(“key2”)}
。顺便说一句,我找不到data“你在jq手册中使用的关键字。它是做什么的?”“data”应该在这里是“inputs”。你想产生JSON输出吗?
def data:
{ "key1": { "key2": {"mykey": {"a": 123},
"another":{"q": "six"} },
"key6": {"key7": {"d": 997} } },
"key3": { "key8": {"key9": {"b": 234} },
"key10": {"mykey": {"d": 997},
"another":{"q": "seven"} } },
"key4": { "key11": {"key5" : {"a": 123} } }
};
def selection(mykey):
. as $in
| reduce (paths(objects) | select(last(.[])==mykey)|.[0:2]) as $path
(null; setpath($path; $in|getpath($path)) );
data | selection("mykey")
{"key1":{"key2":{"mykey":{"a":123},
"another":{"q":"six"}}},
"key3":{"key6":{"mykey":{"d":997},
"another":{"q":"seven"}}}
}