我已经在这里问了一个类似的问题 - Parse json and choose items\keys upon condition,但这一次略有不同。
这是示例:
[
{
"item1": "value123",
"array0": [
{
"item2": "aaa"
}
]
},
{
"item1": "value456",
"array1": [
{
"item2": "bbb"
}
]
},
{
"item1": "value789",
"array2": [
{
"item2": "ccc"
}
]
}
]
我想获得“item1”的值,仅当“item2”具有特定值时才会显示。
让我们说如果item2等于“bbb”,那么我想要回来的就是“value456”。
我试图用jq解决它,就像它在上面提到的问题中对我有用一样,但无济于事,因为我无法从“我”搜索的“更高”级别提取值jq的选择和地图。
答案 0 :(得分:2)
由于递归运算符..
的神奇力量,可以使用更简单的解决方案:
jq -r '.[] | select(.. | .item2? == "bbb").item1'
基本上它的作用是,对于原始数组中的每个(.[]
)对象,仅选择(select
)其中任何以递归方式(..
)命名的键的{ {1}}等于.item2
,然后选择所述对象的"bbb"
属性。
答案 1 :(得分:0)
在jq手册中找到解决方案(#ifthenelse和#Objects) - http://stedolan.github.io/jq/manual
jq -r '{name1: .[].item1, name2: .[].array[].item2} | /
if .item2 == "bbb" then .name1 elif .item2 != "bbb" then empty else empty end'
答案 2 :(得分:0)
如果你发现......的魔力太强大了,以下内容可能会有用。它限制了对" item2"的搜索。键。
def some(condition): reduce .[] as $x
(false; if . then . else $x|condition end);
.[]
| to_entries
| select( some( .value | (type == "array") and some(.item2 == "bbb")) )
| from_entries
| .item1
如果您的jq有任何/ 1,则使用它而不是某些/。
答案 3 :(得分:0)
以下是使用 tostream 和 getpath
的解决方案foreach (tostream|select(length==2)) as [$p,$v] (.;.;
if $p[-1] == "item2" and $v == "bbb" then getpath($p[:-3]).item1 else empty end
)
编辑:我现在意识到foreach E as $X (.; .; R)
形式的过滤器几乎总是被重写为E as $X | R
所以上面的内容实际上就是
(tostream | select(length==2)) as [$p,$v]
| if $p[-1] == "item2" and $v == "bbb" then getpath($p[:-3]).item1 else empty end