jq按参数名转换JSON结果集:多指定键提取语法求助
使用jq从嵌套XML-RPC风格JSON中一次性提取多个指定键值对
我明白你现在的困扰——这个嵌套的JSON结构(看起来是XML-RPC的响应格式)确实有点绕,单键提取没问题,但要一次性拿多个指定键就卡壳了对吧?别担心,我们可以用jq的几个核心特性来解决这个问题。
首先先回顾下你的原始JSON结构:
{ "?xml": { "@version": "1.0", "@encoding": "UTF-8" }, "methodResponse": { "params": { "param": { "value": { "struct": { "member": [ { "name": "severity", "value": { "string": "Important" } }, { "name": "product", "value": { "string": "this is a product name" } }, { "name": "notes", "value": { "string": "Here are some notes" } }, { "name": "references", "value": { "string": "This is a reference" } }, { "name": "release", "value": { "i4": "1" } }, { "name": "last_modified_date", "value": { "string": "2020-03-10 15:21:50.147896" } } ] } } } } } }
你已经能成功提取单个键,比如product的语句:
map(.methodResponse.params.param.value.struct.member[] | select(.name == "product" ).value.string as $product| {$product})
解决方案:一次性提取多个指定键
这里有两种简洁的实现方式,都能得到你期望的输出:
方法一:先转成键值对象再筛选(推荐)
这种方法更灵活,适合需要提取多个键的场景:
[ .methodResponse.params.param.value.struct.member | map({ key: .name, value: (.value | .string // .i4) # 自动匹配value里的string或i4类型 }) | from_entries # 把数组转成键值对对象 | pick(["product", "release", "last_modified_date"]) # 选择需要的键 ]
方法二:手动构建目标对象
如果你需要更明确的控制,也可以直接构建你想要的结构:
[ .methodResponse.params.param.value.struct.member as $members | { product: ($members[] | select(.name == "product").value.string), release: ($members[] | select(.name == "release").value.i4), last_modified_date: ($members[] | select(.name == "last_modified_date").value.string) } ]
结果验证
两种方法运行后,都会输出你期望的格式:
[ { "product": "this is a product name", "release": "1", "last_modified_date": "2020-03-10 15:21:50.147896" } ]
关键语法解释
map({key: .name, value: ...}):把每个member元素转换成jq能识别的键值对格式,方便后续转成对象.value | .string // .i4:用//(空值合并运算符)自动提取value里的实际内容——如果有string键就取它,没有就取i4,完美适配你的混合类型结构from_entries:把键值对数组转换成标准的JSON对象,这样就能用pick快速筛选需要的键pick(["key1", "key2"]):从对象中选择指定的键,省去多次写select的麻烦
内容的提问来源于stack exchange,提问作者juergen-query
相关产品推荐
相关产品推荐

