使用jq将对象移至嵌套对象并遍历未知数量/名称的对象
解决jq移动字段并遍历未知子对象的问题
我来帮你搞定这个jq处理的需求!看你的描述,核心是要把外层的outcome字段移到嵌套的result对象里,同时还要能处理result里那些数量、名称都不确定的子对象对吧?下面直接给你解决方案和详细解释:
核心jq命令(适配所有场景)
针对你的输入(JSON Lines格式,每行一个对象),可以用这个命令:
.outcome as $outcome | .result |= ( if type == "object" then to_entries | map( .value += { outcome: $outcome } ) | from_entries else { outcome: $outcome } end ) | del(.outcome)
逐部分解释
.outcome as $outcome:先把外层的outcome值存到变量$outcome里,避免后续操作中因为字段被删除而取不到值。.result |= (...):对result字段执行更新操作(|=是jq里的更新赋值运算符)。- 判断
result类型:- 如果
result是对象(不管是空还是有子对象):to_entries:把result的键值对转换成[{key: "子对象名称", value: {...}}]格式的数组,这样就能遍历所有未知名称的子对象。map(.value += { outcome: $outcome }):给每个子对象的value部分添加outcome字段,值就是之前存的$outcome。from_entries:把处理后的数组转换回原来的对象格式,保持子对象的名称不变。
- 如果
result不是对象(比如空值):直接把它变成包含outcome的对象。
- 如果
del(.outcome):最后删掉外层的outcome字段,完成字段的移动。
测试示例
示例1:有子对象的输入
输入:
{ "outcome" : "TrBean", "result" : {"TrAct" : { "executiontime" : 16938570, "invocations" : 133863, "waittime" : 4981 }} }
处理后输出:
{ "result": { "TrAct": { "executiontime": 16938570, "invocations": 133863, "waittime": 4981, "outcome": "TrBean" } } }
示例2:空result的输入
输入:
{ "outcome" : "WwwBean", "result" : {} }
处理后输出:
{ "result": { "outcome": "WwwBean" } }
示例3:多子对象的输入
输入:
{ "outcome": "CRFeatureBean", "result": { "CRChannels": { "executiontime": 78127, "invocations": 9983, "waittime": 213 }, "getCRChannels": { "executiontime": 98704, "invocations": 123 } } }
处理后输出:
{ "result": { "CRChannels": { "executiontime": 78127, "invocations": 9983, "waittime": 213, "outcome": "CRFeatureBean" }, "getCRChannels": { "executiontime": 98704, "invocations": 123, "outcome": "CRFeatureBean" } } }
简化版(如果不需要给每个子对象加outcome)
如果你只是想把outcome移到result的顶层,而不是每个子对象里,那命令可以更简单:
.result += { outcome: .outcome } | del(.outcome)
比如空result的输入用这个命令处理后,result会直接包含outcome字段;有子对象的输入,result会同时保留原来的子对象和新增的outcome字段。
内容的提问来源于stack exchange,提问作者user3135149
相关产品推荐
相关产品推荐

