输入
[{
"tags": [{
"value": "domain:sourcing"
},
{
"value": "apiname:src1"
}
]
},
{
"tags": [{
"value": "apiname:fin1"
}]
},
{
"tags": [{
"value": "domain:fin1"
}]
}
]
预期输出
[{
"domain": "sourcing",
"apiname": "src1"
},
{
"domain": "-",
"apiname": "fin1"
},
{
"domain": "fin1",
"apiname": "-"
}
]
到目前为止,我在下面尝试过。
jq 'map(. + (.tags[].value | capture("domain:(?<domain>.+)"))) | map(. + (.tags[].value | capture("apiname:(?<apiname>.+)"))) | map(del(.tags))'
以上cmd的部分输出
[
{
"apiDomain": "sourcing",
"apiName": "src1"
}
]
正如您所看到的,这里的问题是如果没有任何一个捕获组提交,我将完全失去其他对象。输入中的第二个对象具有 apiname 但缺少“domain”,第三个对象具有“domain”但缺少“apiname”。如示例输出中所述,如果没有任何对象,则它们应为“ - ”。
请更新jq命令以实现此目的吗?
答案 0 :(得分:1)
jq
解决方案:
jq '{domain: "-", apiname: "-"} as $o
| map([.tags[] | .value | split(":") | {(.[0]) : .[1]}] | add | $o + .)' input.json
{domain: "-", apiname: "-"} as $o
- 用作模板对象输出:
[
{
"domain": "sourcing",
"apiname": "src1"
},
{
"domain": "-",
"apiname": "fin1"
},
{
"domain": "fin1",
"apiname": "-"
}
]
答案 1 :(得分:1)
这是另一种方法。这假设您的tags
数组仅包含您期望的名称。
map(
reduce (.tags[].value | split(":")) as [$k,$v] (
{domain:"-",apiname:"-"};
.[$k] = $v
)
)
对于没有假设固定名称并且只是展平标签的更通用的解决方案,我执行此操作:
map(
reduce (.tags[].value | split(":")) as [$k,$v] (
del(.tags);
.[$k] = $v
)
)
然后在访问字段时,只需使用替代运算符设置默认值。
(.domain // "-") as $domain
答案 2 :(得分:1)
如果“tag:value”字符串的“value”部分可能包含冒号(“:”),那么使用split
会变得不必要地棘手(甚至可能效率低下),所以它可能更容易使用capture
,或许沿着@RomanPerekhrest建议的行:
{domain:"-", apiname:"-"} as $default
| map([.tags[].value
| capture("(?<k>[^:]*):(?<v>.*)")
| {(.k): .v} ]
| add
| $default + .)