it-swarm.com.ru

Как проверить, существует ли элемент в массиве с jq

У меня есть массив, и мне нужно проверить, существуют ли элементы в этом массиве или получить этот элемент из массива, используя Jq, fruit.json :

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


cat fruit.json | jq '.fruit .Apple' 

не работает

13
idmitriev

Семантика «содержит» совсем не проста. В целом, было бы лучше использовать «индекс» для проверки, имеет ли массив конкретное значение, например,.

.fruit | index( "orange" )

В 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;
22
peak

[ВНИМАНИЕ: СМОТРИТЕ КОММЕНТАРИИ И АЛЬТЕРНАТИВНЫЕ ОТВЕТЫ.]

cat fruit.json | jq '.fruit' | jq 'contains(["orange"])'

2
zinovii

Для будущих посетителей, если у вас есть массив в переменной и вы хотите проверить input против него, и у вас есть jq 1.5 (без IN), ваш лучший вариант - index, но со второй переменной:

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

Это функционально эквивалентно .inputField | IN($storedArray[]).

1
aaa

Если вы открыты для использования чего-то другого, кроме jq, тогда я настоятельно рекомендую Xidel .
С его помощью вы можете объединить JSONiq и XPath/XQuery для обработки JSON!

Для этого просто верните логическое значение:

$ xidel -s fruit.json -e '$json/contains((fruit)(),"Apple")'
true

Чтобы он возвращал элемент, если массив fruit содержит «Apple»:

$ xidel -s fruit.json -e '$json/(fruit)()[contains(.,"Apple")]'
Apple

Выше «запись XPath». «Точечная нотация» (например, jq):

$ xidel -s fruit.json -e '($json).fruit()[contains(.,"Apple")]'
Apple
1
Reino

Чтобы jq возвращал успех, если массив fruit содержит "Apple", а в противном случае ошибка:

jq -e '.fruit[]|select(. == "Apple")' fruit.json >/dev/null

Чтобы вывести найденный элемент, опустите >/dev/null.

0
markusk