我有一个数组,需要使用jq检查该数组中是否存在元素或从该数组中获取该元素,fruit.json:
{
"fruit": [
"apple",
"orange",
"pomegranate",
"apricot",
"mango"
]
}
cat fruit.json | jq '.fruit .apple'
无法工作
我有一个数组,需要使用jq检查该数组中是否存在元素或从该数组中获取该元素,fruit.json:
{
"fruit": [
"apple",
"orange",
"pomegranate",
"apricot",
"mango"
]
}
cat fruit.json | jq '.fruit .apple'
无法工作
'包含'的语义并不直观。一般来说,最好使用“index”来测试数组是否具有特定值,例如:
.fruit | index( "orange" )
然而,如果感兴趣的项本身是一个数组,则一般形式为:
ARRAY | index( [ITEM] )
应该使用,例如:
[1, [2], 3] | index( [[2]] ) #=> 1
如果你的jq有IN/1
,那么更好的解决方案是使用它:
.fruit as $f | "orange" | IN($f[])
如果你的 jq 版本有 first/1
(如 jq 1.5),那么这里是一个快速定义 IN/1
的方法:def IN(s): first((s == .) // empty) // false;
any(_;_)
另一个高效且有时更为方便的替代方法是使用any/2
,例如:
any(.fruit[]; . == "orange")
或者等价地说:
any(.fruit[] == "orange"; .)
要求 jq
在数组 fruit
包含 "apple"
时返回成功,否则返回错误:
jq -e '.fruit|any(. == "apple")' fruit.json >/dev/null
要输出找到的元素,将其更改为
jq -e '.fruit[]|select(. == "apple")' fruit.json
如果搜索的是固定字符串,这个方法可能并不相关,但如果 select
表达式可能匹配不同的值,例如正则表达式,则此方法可能会有用。
要仅输出不同的值,请将结果传递给 unique
。
jq '[.fruit[]|select(match("^app"))]|unique' fruit.json
将搜索以app
开头的所有水果,并输出唯一的值。(请注意,原始表达式必须用[]
括起来才能传递给unique
。)
select
表达式匹配不同值时才打印输出是有意义的,而且fruit
数组一开始就只包含唯一的值,但没关系,我已经详细说明了如何输出不同的值。 - markuska[]|select(cond)
来测试数组中的元素是否满足条件本质上是低效的,除非使用某种机制在找到满足条件的元素后终止搜索。使用any/2
可能是最简单的方法。 - peakany
。对于更高级的情况,当调用者想要显示所有匹配的条目时,仍然需要使用 select
。 - markuskcat fruit.json | jq '.fruit | contains(["orange"])'
对于未来的访问者,如果您恰好拥有一个变量中的数组,并想检查输入是否与其匹配,并且您拥有 jq 1.5(没有 IN),您最好的选择是使用 index
,但需要第二个变量:
.inputField as $inputValue | $storedArray|index($inputValue)
这在功能上相当于 .inputField | IN($storedArray[])
。
在这里进一步阐述,如果您需要将水果数组与另一个水果数组进行过滤,可以像这样进行操作:
注意:请保留HTML标签。
cat food.json | jq '[.fruit[] as $fruits | (["banana", "apple"] | contains([$fruits])) as $results | $fruits | select($results)]'
这个修改后的示例在这里起作用:
jq -r '.fruit | index( "orange" )' fruit.json | tail -n 1
它只获取输出的最后一行。
如果存在,则返回0
。
如果不存在,则返回null
。
cat fruit.json | jq '.fruit as $f | "orange" | in($f[])'
=>jq: error (at <stdin>:9): Cannot check whether string has a string key
。我使用的是 jq 1.5.1 版本。 - Tyler Rickin()
不兼容(如果您可以使用,请告知您的版本)。但是,它可以使用您发布的自定义IN(s)
:cat fruit.json | jq 'def IN(s): . as $in | first(if (s == $in) then true else empty end) ; .fruit as $f | "ap" | IN($f[])'
=>true
- Tyler Rickin
,has
,inside
,contains
- 只有像您建议的index
!)中没有一个的语义是直接的... 至少当涉及到检查数组是否包含字符串这样相似的东西时... - Tyler RickIN
和in
是相同的,但事实并非如此。IN
是一种“SQL风格运算符”,与具有非常混乱语义的in
有所不同。 - ravron