"jq"筛选以选择性地将父字段替换为子字段



我有很多JSON对象,我想在其中转换一些对象以减少冗余并限制一些深度。

例如,给定:

{
"foo": [
{
"foobarList": {
"foobar": 2
}
},
{
"raboofList": {
"raboof": [3, 5, 7]
}
}
],
"bazList": {
"baz": 11
},
"foobar": {
"barbazList": {
"barbaz": [13, 17, 19]
},
"foobazList": {
"foobaz": {
"barfooList": {
"barfoo": [23, 29]
}
}
}
}
}

我想"起重机";以"0"结尾的所有字段的值;"列表";,例如CCD_ 1。

因此,以上内容将转换为:

{
"foo": [
{
"foobar": 2
},
{
"raboof": [3, 5, 7]
}
],
"baz": 11,
"foobar": {
"barbaz": [13, 17, 19],
"foobaz": {
"barfoo": [23, 29]
}
}
}

我试过各种各样的过滤器,但到目前为止,我只能识别";列出$";字段带有:

jq '.. |iterables |to_entries[] |select((has("key")) and (.key|type == "string") and (.key|test("List$")) )'

jq如何实现这种转换?

这里有一个jqplay.org来帮助您入门。

以下内容可以得到您想要的答案,但可能无法在各个方面满足您的期望:

def hoist:
with_entries(if (.key | endswith("List")) 
and (.value | type == "object")
and (.value | keys_unsorted | length==1)
then (.value | keys_unsorted[0]) as $k 
| .key = $k
| .value |= .[$k]
else . end);
walk(if type == "object" then hoist else . end)

如果输入是"可提升";在结构上,您还可以对其流表示进行操作:

[fromstream(tostream | del(.[0][] | select(endswith("List")?)))] | add

演示

最新更新