使用 jq 为 JSON 对象的嵌套数组中的属性展平数组

Posted

技术标签:

【中文标题】使用 jq 为 JSON 对象的嵌套数组中的属性展平数组【英文标题】:Flatten array for properties in nested array of JSON objects using jq 【发布时间】:2019-04-24 06:38:25 【问题描述】:

拥有带有(简化的)Jira 数据的 JSON,例如:


    "issues": [
        
            "key": "TEST-A",
            "fields":  "issuelinks": [] 
        ,
        
            "key": "TEST-B",
            "fields": 
                "issuelinks": [
                     "inwardIssue":  "key": "TEST-1"  ,
                     "outwardIssue":  "key": "TEST-2"  ,
                     "outwardIssue":  "key": "TEST-3"  
                ]
            
        
    ]

希望得到如下输出:

[
     "key": "TEST-A", "inward": null, "outward": null ,
     "key": "TEST-B", "inward": ["TEST-1"], "outward": ["TEST-2", "TEST-3"] 
]

尝试过(暂时忽略内部链接):

cat data.json | \
jq '.issues[] | "key":.key, "outward":.fields.issuelinks[].outwardIssue.key '

但我明白了:

 "key": "TEST-B", "outward": "TEST-1" 
 "key": "TEST-B", "outward": "TEST-2" 
 "key": "TEST-B", "outward": null 

注意:希望 1) TEST-A 用于最后一个,2) TEST-2TEST-3 用于前两个,并希望 3) 将 TEST-2TEST-3 组合在一个数组中。

建议?

【问题讨论】:

【参考方案1】:

让我们从第一次尝试的变体开始:

.issues[]
 | key,
   inward: .fields.issuelinks|map(.inwardIssue.key // empty),
   outward: .fields.issuelinks|map(.outwardIssue.key // empty) 

用你的例子,这会产生:

"key":"TEST-A","inward":[],"outward":[]
"key":"TEST-B","inward":["TEST-1"],"outward":["TEST-2","TEST-3"]

因此需要两次修复才能实现既定目标:

    生成一个数组(例如,将上述表达式括在方括号中) 将空数组替换为 null。

(2) 是可疑的,但很容易实现,例如使用下面定义的辅助函数。

解决方案

def extract(f): map(f // empty) | if length ==0 then null else . end;

.issues
| map(
   key,
    inward: .fields.issuelinks|extract(.inwardIssue.key),
    outward: .fields.issuelinks|extract(.outwardIssue.key))

警告

如果extract 应该保留nullfalse 值,那么它的def 应该相应地修改。

【讨论】:

以上是关于使用 jq 为 JSON 对象的嵌套数组中的属性展平数组的主要内容,如果未能解决你的问题,请参考以下文章

使用 jq 和 bash 为数组中的每个对象运行命令

使用 JQ 展平嵌套的 Json 对象

如何使用 jq 按元素属性值过滤对象数组?

如何使用 JQ 转换此 JSON 数据以依次将每个嵌套数组元素提取到顶层?

JQ将数据从1个文件推送到另一个文件的嵌套数组中

JQ 过滤嵌套对象中的字段