select filter in jq
jq v1.7.1
code:example.json
{
"parent": [
{
"child id": 1,
"contents": [
{
"a": {
"boolean": false,
"number": 100
}
},
{
"a": {
"boolean": true,
"number": 100
}
}
]
},
{
"child id": 2,
"contents": [
{
"a": {
"boolean": true,
"number": 100
}
},
{
"a": {
"boolean": true,
"number": 100
}
}
]
},
{
"child id": 3,
"contents": [
{
"a": {
"boolean": true,
"number": 100
}
},
{
"a": {
"boolean": true,
"number": 100
}
}
]
}
]
}
$ cat example.json | jq '.parent[] | select(.contents[].a.boolean == false and .contents[].a.number == 100)'
結果として、child id = 1 の要素が2回出力されるが、直感に反する気がする
.contents[].a.boolean と .contents[].a.number == 100 という条件が、個別に適用されているということらしい。
child id 1 の contents 配列について考える。1つ目の要素は boolean false, number 100 なので、条件に合致する。2つ目の要素は合致しない。しかし、1つ目の要素と2つ目の要素を組み合わせると、boolean false と number 100 の組み合わせができ、条件に合致してしまうらしい。
code:result
{
"child id": 1,
"contents": [
{
"a": {
"boolean": false,
"number": 100
}
},
{
"a": {
"boolean": true,
"number": 100
}
}
]
}
{
"child id": 1,
"contents": [
{
"a": {
"boolean": false,
"number": 100
}
},
{
"a": {
"boolean": true,
"number": 100
}
}
]
}
わかりやすいように child id 1 だけにして、さらに要素を増やしてみる。
これは要素1に加えて、false と 100 の組み合わせが3つ作れるので、結果は4つになる
code:example.json
{
"parent": [
{
"child id": 1,
"contents": [
{
"a": {
"boolean": false,
"number": 100
}
},
{
"a": {
"boolean": true,
"number": 100
}
},
{
"a": {
"boolean": false,
"number": 1
}
}
]
}
]
}
code:result
cat example.json | jq '.parent[] | select(.contents[].a.boolean == false and .contents[].a.number == 100)'
{
"child id": 1,
"contents": [
{
"a": {
"boolean": false,
"number": 100
}
},
{
"a": {
"boolean": true,
"number": 100
}
},
{
"a": {
"boolean": false,
"number": 1
}
}
]
}
{
"child id": 1,
"contents": [
{
"a": {
"boolean": false,
"number": 100
}
},
{
"a": {
"boolean": true,
"number": 100
}
},
{
"a": {
"boolean": false,
"number": 1
}
}
]
}
{
"child id": 1,
"contents": [
{
"a": {
"boolean": false,
"number": 100
}
},
{
"a": {
"boolean": true,
"number": 100
}
},
{
"a": {
"boolean": false,
"number": 1
}
}
]
}
{
"child id": 1,
"contents": [
{
"a": {
"boolean": false,
"number": 100
}
},
{
"a": {
"boolean": true,
"number": 100
}
},
{
"a": {
"boolean": false,
"number": 1
}
}
]
}
any を以下のように使うことで、.contents[] の要素のいずれかが、.a.boolean == false and .a.number == 100 を満たすときだけ true を返すようになるみたい。
$ cat example.json | jq '.parent[] | select(any(.contents[]; .a.boolean == false and .a.number == 100))'
code:result
{
"child id": 1,
"contents": [
{
"a": {
"boolean": false,
"number": 100
}
},
{
"a": {
"boolean": true,
"number": 100
}
}
]
}