[英]jq how to filter by field value in list
有這樣的輸入:
[
{
"foo": "aaa",
"bar": 111
},
{
"foo": "bbb",
"bar": 111
},
{
"foo": "ccc",
"bar": 222
},
{
"foo": "aaa",
"bar": 333
},
{
"foo": "ddd",
"bar": 444
}
]
我想 select 所有“foo”鍵等於“aaa”或“bbb”的對象。 所以解決方案很明顯:
.[] | select (.foo=="aaa" or.foo=="bbb" )
.[] | select (.foo=="aaa" or.foo=="bbb" )
( https://jqplay.org/s/x7FGo1uQNW )
但我想增強它並將x=y or x=z
替換為 sql'ish styled x in (y,z)
。 我被卡住了,作為自然的嘗試:
.[] | select (.foo in (["aaa", "bbb"]) )
導致錯誤:
jq: 錯誤:語法錯誤,意外 IDENT,期待 ';' 或 ')' (Unix shell 引用問題?)在第 1 行:
我也試過這個:
.[] | select (.foo | in (["aaa", "bbb"]) )
但也不是很好...
jq:錯誤(at:21):無法檢查數組是否有字符串鍵
這甚至可能嗎?
嗯,我設法做到了這一點:
.[] | select(.foo as $tmpvar | ["aaa", "bbb"] | index ($tmpvar ) )
https://jqplay.org/s/g7AyRgARdU
根據這個答案: https://stackoverflow.com/a/46470951/2244766在 1.5 以上的版本中,有一個新的IN
運算符可以讓生活更輕松:
.[] | select(.foo|IN("aaa","bbb"))
SQL 風格的運算符不適合我作為一種直接的選擇機制。 我相信它們有一個非常具體的用例,它們是獨一無二的,而對於其他任何東西來說,它們(充其量)是笨重的。 至少這是我的經驗。 而且我還沒有真正弄清楚那個特定的用例是什么。
以所有這些為背景,我的建議是使用簡單的正則表達式測試:
map(select(.foo | test("aaa|bbb")))
給定示例 JSON:
<~> $ jq . /tmp/so4229.json
[
{
"foo": "aaa",
"bar": 111
},
{
"foo": "bbb",
"bar": 111
},
{
"foo": "ccc",
"bar": 222
},
{
"foo": "aaa",
"bar": 333
},
{
"foo": "ddd",
"bar": 444
}
]
上述過濾器將導致:
<~> $ jq 'map(select(.foo | test("aaa|bbb")))' /tmp/so4229.json
[
{
"foo": "aaa",
"bar": 111
},
{
"foo": "bbb",
"bar": 111
},
{
"foo": "aaa",
"bar": 333
}
]
如果您需要根據 JSON 中的其他數據生成正則表達式,您也可以這樣做:
. as $data | map(select(.bar==111) | .foo) | join("|") as $regex | . = $data | map(select(.foo | test($regex)))
這將導致:
<~> $ jq '. as $data | map(select(.bar==111) | .foo) | join("|") as $regex | . = $data | map(select(.foo | test($regex)))' /tmp/so4229.json
[
{
"foo": "aaa",
"bar": 111
},
{
"foo": "bbb",
"bar": 111
},
{
"foo": "aaa",
"bar": 333
}
]
可能有更好的方法來運行 JSON 兩次(一次獲取正則表達式值,一次使用它)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.