如何使用jq同时修改JSON中的字符串与指定对象属性?
混合类型数组的jq修改方案
问题背景
原始JSON结构如下:
{ "arrays": [ "a_string", { "name": "foo", "properties": [ { "type": "some_type1", "url": "https://example.com", "checksum": "d6fd580fe890b826250aa5d5a88bcdb28839cff4d447ba51536cda4ceae89c4e" } ] }, "another_string", { "name": "bar", "properties": [ { "type": "some_type2", "url": "https://example.org", "checksum": "d6fd580fe890b826250aa5d5a88bcdb28839cff4d447ba51536cda4ceae89c4e" } ] } ] }
需要完成两项修改:
- 将数组中的
"a_string"替换为"b_string" - 修改
name为"foo"的对象的properties字段为[{"type" : "sometypeB", "file" : "filename"}]
之前尝试的命令jq '(.arrays[]| select(.name == "foo")).sources |= [{"type" : "sometypeB", "file" : "filename"}]'执行失败,原因是数组中存在字符串类型元素,select(.name == "foo")会尝试访问字符串的name属性,导致类型错误。
解决方案
使用jq的类型判断和条件分支处理混合类型数组,完整命令如下:
jq '.arrays |= map( if type == "string" then if . == "a_string" then "b_string" else . end elif type == "object" and .name == "foo" then .properties = [{"type": "sometypeB", "file": "filename"}] else . end )' input.json
命令解释
.arrays |= map(...):对arrays数组进行遍历处理,替换原数组- 第一个分支:判断元素为字符串时,检查是否等于
"a_string",是则替换为"b_string",否则保持原样 - 第二个分支:判断元素为对象且
name字段等于"foo"时,修改其properties字段 - 最后一个分支:其他元素(比如
"another_string"和name为bar的对象)保持不变
执行结果
执行后得到的JSON与期望一致:
{ "arrays": [ "b_string", { "name": "foo", "properties": [ { "type": "sometypeB", "file": "filename" } ] }, "another_string", { "name": "bar", "properties": [ { "type": "some_type2", "url": "https://example.org", "checksum": "d6fd580fe890b826250aa5d5a88bcdb28839cff4d447ba51536cda4ceae89c4e" } ] } ] }
内容的提问来源于stack exchange,提问作者user22990699
相关产品推荐
相关产品推荐

