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

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

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


cat fruit.json | jq '.fruit .apple' 

не работает

Ответы

Ответ 1

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

.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;

Ответ 2

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

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

Ответ 3

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

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

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

Ответ 4

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

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

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

Ответ 5

Если вы открыты для использования чего-то другого, кроме 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

Ответ 6

если вы не ограничены jq, вы можете легко выполнить запрос с помощью jtc:

bash $ cat fruit.json | jtc -w'[fruit]<apple>' 
"apple"
bash $ cat fruit.json | jtc -w'[fruit]<plum>' 
bash $ 

Ответ 7

Кроме того, в настоящее время разработан другой альтернативный инструмент Unix для манипуляции JSON, предлагающий новый подход для обработки JSON - walk-path утилита Unix jtc.

Вот несколько примеров того, как выполнить задание:

1. Когда запись существует - она будет напечатана, в противном случае возвращается пустая строка:

bash $ <fruit.json jtc -w'<mango>'
"mango"
bash $ <fruit.json jtc -w'<mangos>'
bash $ 

2. Если запись существует, напечатайте true, в противном случае напечатайте false:

bash $ <fruit.json jtc -w'<res:false>f<mango><res:true>v' -T'{{res}}'
true
bash $ <fruit.json jtc -w'<res:false>f<mangos><res:true>v' -T'{{res}}'
false
bash $ 

3. Когда запись присутствует, напечатайте ее, в противном случае напечатайте "FALSE":

bash $ <fruit.json jtc -w'<r:"FALSE">f<mango><r>v' -T'{{r}}'
"mango"
bash $ <fruit.json jtc -w'<r:"FALSE">f<mangos><r>v' -T'{{r}}'
"FALSE"
bash $ 

PS> Раскрытие информации: я являюсь создателем инструмента jtc - shell cli для операций JSON