Вопрос или проблема
С помощью jq, возможно ли обновить значение свойства объекта, которое содержит определенное значение в другом свойстве?
В примере ниже я хочу установить значение свойства “value” всех объектов, у которых “keyname” = “foo”.
Пример .json файла выглядит так:
"root" : {
"instances": [
{
"name": "1",
"configs": [
{
"keyname": "foo",
"value": "" // <- обновить/установить это
},
{
"keyname": "barrr",
"value": "barrrr"
}
]
},
{
"name": "2",
"configs": [
{
"keyname": "foo",
"value": "" // <- обновить/установить это
},
{
"keyname": "buzzz",
"value": "buzzz"
}
]
}
]
}
Я попробовал это, но безуспешно, появляется ошибка о том, что массив не является строкой:
jq '(.root.instances.configs[] | select(.keyname==foo)).value = foo'
Предполагая, что ваш JSON-документ правильно сформирован, чего нет в вашем примере, так как он содержит несколько ошибок:
$ cat file
{
"root": {
"instances": [
{
"name": "1",
"configs": [
{
"keyname": "foo",
"value": ""
},
{
"keyname": "barrr",
"value": "barrrr"
}
]
},
{
"name": "2",
"configs": [
{
"keyname": "foo",
"value": ""
},
{
"keyname": "buzzz",
"value": "buzzz"
}
]
}
]
}
}
$ jq '( .root.instances[].configs[] | select(.keyname == "foo") ).value = "foo"' file
{
"root": {
"instances": [
{
"name": "1",
"configs": [
{
"keyname": "foo",
"value": "foo"
},
{
"keyname": "barrr",
"value": "barrrr"
}
]
},
{
"name": "2",
"configs": [
{
"keyname": "foo",
"value": "foo"
},
{
"keyname": "buzzz",
"value": "buzzz"
}
]
}
]
}
}
Это выражение jq
обновляет значение ключа .value
на строку foo
. Обновляемый ключ выбирается из одного из элементов .root.instances[].configs[]
. Обратите внимание, что .root.instances
является массивом, и каждый элемент .configs
в каждом из его элементов также является массивом. Оператор select()
проверяет ключ .keyname
со строкой foo
.
Сделать ключ запроса и новое значение переменными можно следующим образом:
jq --arg querykey 'foo' \
--arg newval 'The train said "choo choo"' \
'( .root.instances[].configs[] | select(.keyname == $querykey) ).value = $newval' file
Это создает две внутренние переменные jq
с названиями $querykey
и $newval
. Их значения будут корректно кодироваться так, чтобы, например, $newval
мог содержать двойные кавычки, как показано выше.
Ответ или решение
Использование утилиты jq
для обновления значений свойств объектов в JSON-файле на основании определенных условий является мощной техникой в обработке данных. В данном вопросе мы рассматриваем необходимость обновления значения свойства "value" в объектах, где свойство "keyname" имеет значение "foo". Это довольно распространенный сценарий, с которым часто сталкиваются специалисты в области информационных технологий.
Решение задачи с использованием jq
Анализ JSON-структуры
Предположим, мы имеем следующий JSON:
{
"root": {
"instances": [
{
"name": "1",
"configs": [
{
"keyname": "foo",
"value": ""
},
{
"keyname": "barrr",
"value": "barrrr"
}
]
},
{
"name": "2",
"configs": [
{
"keyname": "foo",
"value": ""
},
{
"keyname": "buzzz",
"value": "buzzz"
}
]
}
]
}
}
Обновление с применением jq
Для того чтобы обновить значение "value" для всех объектов, содержащих "keyname" равное "foo", используйте следующий jq
-запрос:
jq '( .root.instances[].configs[] | select(.keyname == "foo") ).value = "foo"' файл.json
Этот запрос выполняет следующие действия:
- Итерация по массивам: Мы проходим через каждый объект в "instances" и затем внутри каждого — через каждый объект в "configs".
- Условный выбор: Функция
select(.keyname == "foo")
выбирает только те объекты, где ключ "keyname" равен "foo". - Обновление значения: Изменяем значение "value" на "foo".
Использование переменных в jq
Для большей гибкости можно заменить жестко заданные значения на переменные. Это полезно, если вы хотите использовать разные значения без изменения основного запроса:
jq --arg querykey 'foo' --arg newval 'Новое значение' \
'( .root.instances[].configs[] | select(.keyname == $querykey) ).value = $newval' файл.json
В этом запросе мы определяем две переменные:
$querykey
: значение для поиска в "keyname".$newval
: новое значение для "value".
Заключение
Использование jq
предоставляет мощные инструменты для работы с JSON-данными. Правильное применение этих инструментов требует четкого понимания структуры данных и условий задания. Приведенные примеры помогут вам успешно обновлять JSON-документы, используя эффективно написанные и адаптивные команды jq
.
Пожалуйста, не забывайте проверять структуру JSON-файлов для обеспечения корректности перед выполнением операций, особенно в продакшн-средах.