有人知道如何实现吗?
我有一个带有嵌套数组的数组,例如tagNames,我想选择tagNames完全包含“自动测试”而不是“自动测试2”的所有项目。
{
"servers":[
{"id":1, "tagNames": ["auto-test", "xxx"]},
{"id":2, "tagNames": ["auto-test2", "xxxx"]}
]
}
到目前为止,我正在使用
echo '{"servers":[{"id":1,"tagNames":["auto-test","xxx"]},{"id":2,"tagNames":["auto-test2","xxxx"]}]}' |\
jq '[ .servers[] | select(.tagNames | contains(["auto-test"])) ]'
我有两张唱片,但我只想要第一张。
[
{
"id": 1,
"tagNames": [
"auto-test",
"xxx"
]
},
{
"id": 2,
"tagNames": [
"auto-test2",
"xxxx"
]
}
]
所以我想要这个:
[
{
"id": 1,
"tagNames": [
"auto-test",
"xxx"
]
}
]
有什么主意吗?
答案 0 :(得分:2)
您不应该使用contains/1
,因为它不能像您期望的那样工作,特别是在处理字符串时。它将递归检查是否包含所有部件。因此,它不仅会检查字符串是否包含在数组中,而且还会检查字符串是否也是子字符串。
您需要写出条件,并根据条件检查所有标签。
[.servers[] | select(any(.tagNames[]; . == "auto-test") and all(.tagNames[]; . != "auto-test2"))]
答案 1 :(得分:1)
一种方法是使用index/1
,例如
.servers[]
| select( .tagNames | index("auto-test"))
这将产生:
{"id":1,"tagNames":["auto-test","xxx"]}
如果要将其包装在数组中,则可以(例如)将上面的过滤器包装在方括号中。
答案 2 :(得分:0)
另一种解决方案是使用以下成语:first(select(_)):
jq '.servers[] | first(select(.tagNames[]=="auto-test"))' file
如果省略first
,则servers
数组中的同一项目可能会发射多次。