2016-03-22 2 views
3

Мне нужно изменить значение набора ключей (определенного в переменной) в объекте JSON с помощью jq.Изменение значений JSON на основе массива ключей с помощью jq

В качестве примера, у меня есть объект JSON:

{ 
    foo: { 
     bar: 1, 
     baz: 2, 
     qux: 3 
    } 
} 

и следующую переменную:

update_keys = ["bar", "baz"] 

Я хотел бы сказать, 'изменить значение ключей в update_keys для X'.

следующие работы:

.foo = (.foo | 
     to_entries | 
     map(if .key == "bar" or .key == "baz" 
     then . + { "value":"X" } 
     else . 
     end) | 
     from_entries) 

Но вместо if .key == "bar" or .key == "baz" Ищу способ сказать if .key in update_keys или подобную логику.

+0

Не могли бы вы рассказать о том, каким должен быть результат. Не уверен, хотите ли вы расширить update_keys или изменить.foo –

+0

Я хочу обновить foo, изменив значения ключей, определенных в массиве update_keys (все ключи меняются на одно значение) – fusio

+0

Является ли 'update_keys' уже переменной, которую вы определили в' jq'? –

ответ

1

Здесь вы идете.

Фильтр

.foo |= with_entries(.value = if ([.key] | inside(["bar", "baz"])) then "X" else .value end) 

Входной

{ 
    "foo": { 
     "bar": 1, 
     "baz": 2, 
     "qux": 3 
    } 
} 

Выход

{ 
    "foo": { 
    "bar": "X", 
    "baz": "X", 
    "qux": 3 
    } 
} 

Заканчивать поваренная книга для более рецептах и методы jq использования:
https://github.com/stedolan/jq/wiki/Cookbook

+0

oh wow, спасибо: D – fusio

0

Вот несколько иной подход с использованием --argjson спараметрировать update_keys и index/1:

$ cat update.jq 
.foo |= with_entries(. as $in 
      | if $update_keys | index($in.key) then .value = "X" else empty end) 

$ update_keys='["bar", "baz"]' 

$ jq --argjson update_keys "$update_keys" -f update.jq input.json 

Output: 

{ 
    "foo": { 
    "bar": "X", 
    "baz": "X" 
    } 
} 
0

В этой проблемы, так как $update_keys это просто массив все, что необходимо,

.foo[ $update_keys[] ] = "X" 

eg если

["bar","baz"] as $update_keys 
| .foo[ $update_keys[] ] = "X" 

в filter.jq и data.json содержит (slighty скорректированные) данные

{ 
    "foo": { 
    "bar": 1, 
    "baz": 2, 
    "qux": 3 
    } 
} 

затем

jq -M -f filter.jq data.json 

производит

{ 
    "foo": { 
    "bar": "X", 
    "baz": "X", 
    "qux": 3 
    } 
} 

Если вы хотите ра ss в значении для ключей обновления вместо определения его в вашем скрипте вы можете легко использовать --argjson, как показывает ответ peak.