使用jq流模式解析含重复keys属性的嵌套JSON并提取目标字段
嵌套JSON多同名keys属性解析问题
我需要解析如下嵌套结构的JSON文件,但文件中存在多处同名的keys属性,导致解析难度很高:
{ "jobname": { "keys": { "jobid":"E000295", "car":"BMW" }, "property":{ "doctype":"File", "areadesc":[ { "areaid":"qaz", "weather":"hot", }, { "areaid":"wsx", "weather":"code", }, { "areaid":"edc", "weather":"hot", }, { "areaid":"rfv", "weather":"hot", } ] }, "toolJobs":[ { "keys":{ "toolid":"123" }, "reports":[ { "keys":{ "oiltype":"a", "oilcountry":"us" }, "property":{"reportid":"001"}, "datas":[ { "keys":{"areaid":"qaz"}, "data":[ { "time": "2021-01-01", "value": 1 }, { "time": "2021-01-02", "value": 3 }, ] }, { "keys":{"areaid":"wsx"}, "data":[ { "time": "2021-01-03", "value": 5 }, { "time": "2021-01-04", "value": 7 }, ] }, ] }, { "keys":{ "oiltype":"b", "oilcountry":"china" }, "property":{"reportid":"002"}, "datas":[ { "keys":{"areaid":"edc"}, "data":[ { "time": "2021-01-05", "value": 2 }, { "time": "2021-01-06", "value": 4 }, ] }, { "keys":{"areaid":"rfv"}, "data":[ { "time": "2021-01-07", "value": 6 }, { "time": "2021-01-08", "value": 8 }, ] }, ] } ] } ] } }
目前我使用以下jq代码可以得到基础结果,但缺少oiltype、oilcountry、reportid、areaid等字段:
cat tmp1.json | jq -cn --stream ' [fromstream( 1|truncate_stream(inputs) | (.[0][:2] | index("keys")) as $ix | if $ix then .[0] |= .[1+$ix:] else (.[0] | index("toolJobs")) as $iy | (.[0][$iy:$iy+3] | index("keys")) as $iz | if $iz then .[0] |= .[1+$iy+$iz:] else (.[0] | index("data")) as $ik | if $ik then .[0] |= .[$ik:] else empty end end end )] | .[0] as $header | .[1] as $tool | [.[2:][] | ($header+ $tool+.)] | .'
该代码返回结果如下:
[ {"jobid":"E000295","car":"BMW","toolid":"123","data":[{"time":"2021-01-01","value":1},{"time":"2021-01-02","value":3}]}, {"jobid":"E000295","car":"BMW","toolid":"123","data":[{"time":"2021-01-03","value":5},{"time":"2021-01-04","value":7}]}, {"jobid":"E000295","car":"BMW","toolid":"123","data":[{"time":"2021-01-05","value":2},{"time":"2021-01-06","value":4}]}, {"jobid":"E000295","car":"BMW","toolid":"123","data":[{"time":"2021-01-07","value":6},{"time":"2021-01-08","value":8}]}]
我也尝试了以下修改后的代码:
cat tmp1.json | jq -cn --stream ' [fromstream( 1|truncate_stream(inputs) | (.[0][:2] | index("keys")) as $ix | if $ix then .[0] |= .[1+$ix:] else (.[0] | index("toolJobs")) as $iy | (.[0][$iy:$iy+3] | index("keys")) as $iz | if $iz then .[0] |= .[1+$iy+$iz:] else (.[0] | index("data")) as $ik | if $ik then .[0] |= .[$ik:] else (.[0] | index("reports")) as $iw | (.[0][$iw:$iw+3] | index("property")) as $ii | if $ii then (.[0] |= .[$iw+$ii:]) else (.[0] | index("keys")) as $ij | if $ij then (.[0] |= .[$ij:]) else empty end end end end end )] | .[0] as $header | .[1] as $prjob | [.[2:][] | ($header + $prjob + .)] | .'
但返回结果不符合预期:
[ {"jobid":"E000295","car":"BMW","property":{"reportid":"001"},"toolid":"123","keys":{"oiltype":"a","oilcountry":"us","areaid":"qaz"},"data":[{"time":"2021-01-01","value":1},{"time":"2021-01-02","value":3}]}, {"jobid":"E000295","car":"BMW","property":{"doctype":"File","areadesc":[{"areaid":"qaz","weather":"hot"},{"areaid":"wsx","weather":"code"},{"areaid":"edc","weather":"hot"},{"areaid":"rfv","weather":"hot"}]},"toolid":"123","keys":{"areaid":"wsx"},"data":[{"time":"2021-01-03","value":5},{"time":"2021-01-04","value":7}]}, {"jobid":"E000295","car":"BMW","property":{"reportid":"002"},"toolid":"123","keys":{"oiltype":"b","oilcountry":"china","areaid":"edc"},"data":[{"time":"2021-01-05","value":2},{"time":"2021-01-06","value":4}]}, {"jobid":"E000295","car":"BMW","property":{"doctype":"File","areadesc":[{"areaid":"qaz","weather":"hot"},{"areaid":"wsx","weather":"code"},{"areaid":"edc","weather":"hot"},{"areaid":"rfv","weather":"hot"}]},"toolid":"123","keys":{"areaid":"rfv"},"data":[{"time":"2021-01-07","value":6},{"time":"2021-01-08","value":8}]} ]
我期望得到的结果如下:
[ { "jobid":"E000295", "car":"BMW", "toolid":"123", "oiltype":"a", "oilcountry":"us", "reportid":"001", "areaid":"qaz", "data":[ { "time": "2021-01-01", "value": 1 }, { "time": "2021-01-02", "value": 3 }, ] }, { "jobid":"E000295", "car":"BMW", "toolid":"123", "oiltype":"a", "oilcountry":"us", "reportid":"001", "areaid":"wsx", "data":[ { "time": "2021-01-03", "value": 5 }, { "time": "2021-01-04", "value": 7 }, ] }, { "jobid":"E000295", "car":"BMW", "toolid":"123", "oiltype":"b", "oilcountry":"china", "reportid":"002", "areaid":"edc", "data":[ { "time": "2021-01-05", "value": 2 }, { "time": "2021-01-06", "value": 4 }, ] }, { "jobid":"E000295", "car":"BMW", "toolid":"123", "oiltype":"b", "oilcountry":"china", "reportid":"002", "areaid":"rfv", "data":[ { "time": "2021-01-07", "value": 6 }, { "time": "2021-01-08", "value": 8 }, ] } ]
请问该如何修改jq命令才能实现上述需求?
内容的提问来源于stack exchange,提问作者CYC
相关产品推荐
相关产品推荐

