2016-12-28 5 views
4

Я хотел бы изменить что-то вроде следующего JSON:Изменение вложенного JSON условно с помощью JQ

{ 
    "foobar": { 
    "a": { 
     "adkjfe": { 
     "A": 1, 
     "foo": "bar" 
     } 
    }, 
    "b": { 
     "ekjaei": { 
     "A": 2, 
     "bar": "foo" 
     } 
    } 
    } 
} 

добавить больше данных говорят {"baz": ["bing", "bop"]} к родителю А, если А = 1. Предполагая, что я не знаю родительского ключа, оставив остальную часть json нетронутой. Я пробовал много разных вещей, в том числе:

.foobar | .. | .. | .[] | if select(.A==1) then . += {"baz": "bing"} else . end 

, который дает мне ошибку и только мой измененный раздел.

В результате, в этом случае, что я хотел бы видеть это:

{ 
    "foobar": { 
    "a": { 
     "adkjfe": { 
     "A": 1, 
     "foo": "bar", 
     "baz": ["bing", "bop"] 
     } 
    }, 
    "b": { 
     "ekjaei": { 
     "A": 2, 
     "bar": "foo" 
     } 
    } 
    } 
} 

ответ

2

Выберите только поля, которые типа object и соответствовать вашему условию (A == 1):

jq '(.foobar | .. | select(type == "object" and .A == 1)) |= .+ {"baz": ["bing", "bop"]}' test.json 

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

+0

Работает как buttah! Спасибо! – dbarnett

2

В общем, лучше избегать .., если это возможно, по соображениям эффективности. В данном случае это сделает следующее:

(.foobar[][] | select(.A == 1)) |= .+ {"baz":["bing", "bop"]} 
Смежные вопросы