如何使用jq检查数组中是否存在元素

idm*_*iev 18 membership arrays bash json jq

我有一个数组,我需要检查该数组中是否存在元素,或者使用jq,fruit.json从数组中获取该元素:

{
    "fruit": [
        "apple", 
        "orange",
        "pomegranate",
        "apricot",
        "mango"
    ]
}


cat fruit.json | jq '.fruit .apple' 
Run Code Online (Sandbox Code Playgroud)

不起作用

pea*_*eak 29

"包含"的语义根本不是直截了当的.通常,最好使用'index'来测试数组是否具有特定值,例如

.fruit | index( "orange" )
Run Code Online (Sandbox Code Playgroud)

IN/1

如果你的jq有IN/1更好的解决方案就是使用它:

.fruit as $f | "orange" | IN($f[])
Run Code Online (Sandbox Code Playgroud)

如果你的jq有first/1(和jq 1.5一样),那么这里有一个快速定义IN/1:

def IN(s): first((s == .) // empty) // false;
Run Code Online (Sandbox Code Playgroud)

  • 我很困惑,假设函数的查找不区分大小写,并且这个“IN”与“in”相同,但事实并非如此。`IN` 是一个[“SQL 风格的运算符”](https://stedolan.github.io/jq/manual/#SQL-StyleOperators),与 `in` 不同,后者的语义非常混乱。 (5认同)
  • 你怎么避免这个错误?`cat fruit.json | jq'.fruit为$ f | "橙色"| in($ f [])'`=>`jq:error(at <stdin>:9):无法检查字符串是否有字符串键`.我在jq 1.5.1. (2认同)
  • 请告诉我有一个更简洁的方法来执行此操作(适用于字符串值,并且不将子字符串计为匹配).没有这些简单明了的函数(`in`,`has`,`inside`,`contains`-only`index`,就像你建议的那样!)的语义很简单..至少在涉及到如此相似的东西时检查数组是否包含字符串... (2认同)

tef*_*ozi 6

[警告:请参阅评论和替代答案。]

cat fruit.json | jq '.fruit | contains(["orange"])'
Run Code Online (Sandbox Code Playgroud)

  • 此外,`contains` 只要求`"orange"` 是数组元素的*子串*。 (12认同)

mar*_*usk 6

jq如果数组fruit包含则返回成功"apple",否则返回错误:

jq -e '.fruit|any(. == "apple")' fruit.json >/dev/null
Run Code Online (Sandbox Code Playgroud)

要输出找到的元素,请更改为

jq -e '.fruit[]|select(. == "apple")' fruit.json
Run Code Online (Sandbox Code Playgroud)

如果搜索固定字符串,这不是很相关,但可能是select表达式可能匹配不同的值,例如,如果它是正则表达式。

要仅输出不同的值,请将结果传递给unique

jq '[.fruit[]|select(match("^app"))]|unique' fruit.json
Run Code Online (Sandbox Code Playgroud)

将搜索所有以 开头的水果app,并输出唯一值。(请注意,必须将原始表达式包裹起来[]才能传递给unique。)


aaa*_*aaa 5

对于未来的访问者,如果您碰巧将数组放在一个变量中并想根据它检查输入,并且您有 jq 1.5(没有 IN),那么您最好的选择是index使用第二个变量:

.inputField as $inputValue | $storedArray|index($inputValue)

这在功能上等同于.inputField | IN($storedArray[]).