Условно добавьте массив json, используя jq и bash - PullRequest
0 голосов
/ 28 января 2020

Я пытаюсь добавить массив json с одним элементом массива к json. И это должно быть добавлено, только если это еще не существует. Пример json ниже.

{
    "lorem": "2.0",
    "ipsum": {
        "key1": "value1",
        "key2": "value2"
    },
    "schemes": ["https"],
    "dorum" : "value3" 
}

Выше json, где существует "schemes": ["https"],. Я пытаюсь добавить схемы, только если они не существуют, используя приведенный ниже код.

scheme=$( cat rendertest.json | jq -r '. "schemes" ')
echo $scheme
schem='["https"]'
echo "Scheme is"
echo $schem
if [ -z $scheme ]
then
echo "all good"
else 
jq --argjson argval  "$schem"  '. += { "schemes" : $schem }' rendertest.json > test.json
fi

Я получаю приведенную ниже ошибку в файле, когда элемент массива json «схемы» не существует. Он возвращает ноль и ошибки. Любая идея, где я иду не так?

null
Scheme is
["https"]
jq: error: schem/0 is not defined at <top-level>, line 1:
. += { "schemes" : $schem }                   
jq: 1 compile error

Редактировать: вопрос не в том, как передать bash переменные в JQ.

1 Ответ

2 голосов
/ 28 января 2020

Просто используйте явное условие if, которое проверяет атрибут schemes на уровне root структуры JSON

schem='["https"]'

После установки вышеуказанной переменной в вашей оболочке, запустите следующий фильтр

jq --argjson argval "$schem" 'if has("schemes")|not then .+= { schemes: $argval } else . end' json

Аргумент сразу после поля --argjson должен использоваться в контексте jq, но вы пытались использовать $schem в контексте, который неверно.

Вы можете даже go на один уровень дальше и проверить, присутствует ли schemes, и если не содержит ожидаемое вами значение, то выполните перезапись. Измените фильтр в пределах '..' на

( has("schemes")|not ) or .schemes != $argval )

, который можно запустить как

jq --argjson argval "$schem" 'if ( (has("schemes")|not) or .schemes != $argval) then (.schemes: $argval) else . end'
...