Проверка существования элемента уровня root с помощью jq - PullRequest
2 голосов
/ 22 января 2020

Учитывая структуру JSON, такую ​​как ниже, я хочу проверить наличие ключа верхнего уровня sys/.

{                                                                                                                                                             
  "abc/": {                                                                                                                                             
    "uuid": "fd"
   },
 "sys/": {                                                                                                                                                   
    "uuid": "id2"
  }
}

Я пробовал различные конструкции, такие как jq "sys/" или jq "sys/.uuid" но я получаю ошибки компиляции и / или ошибки, такие как "jq: error: sys / 0 не определено в строке 1:"

Обратите внимание, что важно, чтобы код результата ($? ) из jq возвращает корректно, чтобы отразить фактический результат (потому что он используется в тесте управления конфигурацией).

Ответы [ 2 ]

5 голосов
/ 22 января 2020

Вам просто нужно использовать атрибут has, который возвращает логическое значение в зависимости от наличия упомянутого ключа

jq 'has("sys/")'

Обратите внимание, что вы можете настроить jq для возврата строки bool или даже null, но ни один из них не может быть напрямую использован в условной оболочке, которая использует только коды выхода 0 или 1.

Если вы хотите, чтобы результат jq использовался в условном выражении оболочки вы можете вернуть код завершения. Есть опция, которая поддерживает это. Из документации

-e / --exit-status:

Устанавливает состояние выхода jq в 0, если последние выходные значения не были ни false, ни null, 1 если последнее выходное значение было либо false, либо null, либо 4, если действительный результат не был получен.

Так что используйте это для ваших данных JSON

jq -e 'has("sys/")' json > /dev/null
echo $?
0

, но для несуществующего ключа sys1 он выдает

jq -e 'has("sys1/")' json > /dev/null
echo $?
1

. Обратите внимание, что > /dev/null подавляет stdout, выбрасываемый при применении фильтра, который является логическим значением строки. Если ваша версия jq не поддерживает эту опцию или вы ищете альтернативный способ сделать это, вы можете напрямую сопоставить строку, возвращаемую из фильтра has(), вместо оценки кода выхода, т.е.

if [ $(jq 'has("sys/")' json) = "true" ]; then
    printf '%s\n' 'key present'
fi
0 голосов
/ 22 января 2020

Добавление к предыдущему ответу - это способ сделать это в Python 3, если кто-то не может установить jq :

#!/usr/local/bin/python3

import json

obj=json.loads("""{                                               
  "abc/": {                                                              
    "uuid": "fd"
   },
 "sys/": {                                                                
    "uuid": "id2"
  }
}""")

if 'sys/' in obj:
    exit(0)
else :
    exit(1)
...