如何组合(连接)JSON 个包含公共键名称但在 jq 中具有唯一值的对象
How to combine (concatenate) JSON objects which contain a common key name but unique values in jq
使用 jq 命令,我试图将一些数据转换为特定格式
我有一个示例 JSON 集:
{
"site": [
{
"uuid":“23451fae-a14f-49d1-a096-8f033f69dc80”,
"testtype": "Scheduled",
"name": "JANE DOE HEAD OFFICE",
"equip": "唯一物品一"
}
]
}
{
"site": [
{
"uuid":“23451fae-a14f-49d1-a096-8f033f69dc80”,
"testtype": "Scheduled",
"name": "JANE DOE HEAD OFFICE",
"equip": "独特物品二"
}
]
}
{
"site": [
{
"uuid":“23451fae-a14f-49d1-a096-8f033f69dc80”,
"testtype": "Scheduled",
"name": "JANE DOE HEAD OFFICE",
"equip": "独特物品三"
}
]
}
我想提取 unique 值 (equip
);
- 来自数据集中具有 常见 名称的已知位置(
site
); 和
将值与我可以更改的 字符串 分隔符连接起来;
为了获得这样的输出:(显示为 comma
作为我选择的分隔符):
{
"site": [
{
"uuid":“23451fae-a14f-49d1-a096-8f033f69dc80”,
"testtype": "Scheduled",
"name": "JANE DOE HEAD OFFICE",
"equip": "\"Unique Item One\",\"Unique Item Two\",\"Unique Item Three\""
}
]
}
只是解决 equip
值作为第一步;我尝试使用样本数据集的一些命令组合(将输出裁剪到每个 k:v 对):
- 尝试 -j 标志:(问题:Tailing 逗号)
jq -jr '.site[].equip | . + ","'
独特物品一,独特物品二,独特物品三,
使用Reduce(问题:前导逗号)
jq -j '.site[].equip |减少 。作为 $item (""; "" + "," + ($item))'
,独特物品一,独特物品二,独特物品三
使用join():(问题:没有正确使用所以根本没有comma
)
jq'.site |地图(.equip)|加入(”,”)'
"Unique Item One"
"Unique Item Two"
"Unique Item Three"
- 使用@csv:(问题:尾随
comma
,以及甚至不是来自@csv)
jq -rj '.site[].equip + "," | [.] | @csv'
"Unique Item One,""Unique Item Two,""Unique Item Three,"
我尝试过的其他方法导致前导逗号,或者递归地连接和字符串化每个对象,但我得出的结论是我从根本上看是错误的。
如果我引入外部输入进行测试,(在这种情况下传递--arg) 使用 赋值运算符 ,我可以足够接近期望的结果以进一步取得进展,但它仍然为每个结果生成一行,并且变得非常不灵活:
jq -c --arg new2 "Unique Item Two" --arg new3 "Unique Item Three" -r '.site[] |= .equip + "," + $new2 + "," + $new3 |添加| .[] | tojson'
"Unique Item One,Unique Item Two,Unique Item Three"
现在我不确定我是否遗漏了一些简单的东西,或者这是否需要一些复杂的计数和迭代。
注意:我知道从外部切断输出是多么容易 - 有某些原因我想完全在 jq,因为它确实是我想要正确的结构。
您可以将它们分组以确定需要组合哪些 equip
值,然后您可以构建您的字符串。
$ jq -n --arg delim ',' '{
site: [inputs.site[]]
| group_by(.uuid)
| map({
uuid: .[0].uuid,
testtype: .[0].testtype,
name: .[0].name,
equip: (map(.equip | tojson) | unique | join($delim))
})
}' input.json
这会产生:(注意:不一定保留项目顺序)
{
"site": [
{
"uuid": "23451fae-a14f-49d1-a096-8f033f69dc80",
"testtype": "Scheduled",
"name": "JANE DOE HEAD OFFICE",
"equip": "\"Unique Item One\",\"Unique Item Two\",\"Unique Item Three\""
}
]
}
如果字符串看起来像 csv 数据并且需要转义,请务必这样做。假设引号需要转义,你可以修改这部分:
map(.equip | gsub("\"";"\"\"") | tojson)
使用 jq 命令,我试图将一些数据转换为特定格式
我有一个示例 JSON 集:
{ "site": [ { "uuid":“23451fae-a14f-49d1-a096-8f033f69dc80”, "testtype": "Scheduled", "name": "JANE DOE HEAD OFFICE", "equip": "唯一物品一" } ] } { "site": [ { "uuid":“23451fae-a14f-49d1-a096-8f033f69dc80”, "testtype": "Scheduled", "name": "JANE DOE HEAD OFFICE", "equip": "独特物品二" } ] } { "site": [ { "uuid":“23451fae-a14f-49d1-a096-8f033f69dc80”, "testtype": "Scheduled", "name": "JANE DOE HEAD OFFICE", "equip": "独特物品三" } ] }
我想提取 unique 值 (equip
);
- 来自数据集中具有 常见 名称的已知位置(
site
); 和 将值与我可以更改的 字符串 分隔符连接起来;
为了获得这样的输出:(显示为
comma
作为我选择的分隔符):
{ "site": [ { "uuid":“23451fae-a14f-49d1-a096-8f033f69dc80”, "testtype": "Scheduled", "name": "JANE DOE HEAD OFFICE", "equip": "\"Unique Item One\",\"Unique Item Two\",\"Unique Item Three\"" } ] }
只是解决 equip
值作为第一步;我尝试使用样本数据集的一些命令组合(将输出裁剪到每个 k:v 对):
- 尝试 -j 标志:(问题:Tailing 逗号)
jq -jr '.site[].equip | . + ","'
独特物品一,独特物品二,独特物品三,
使用Reduce(问题:前导逗号)
jq -j '.site[].equip |减少 。作为 $item (""; "" + "," + ($item))'
,独特物品一,独特物品二,独特物品三使用join():(问题:没有正确使用所以根本没有
comma
)jq'.site |地图(.equip)|加入(”,”)'
"Unique Item One" "Unique Item Two" "Unique Item Three"
- 使用@csv:(问题:尾随
comma
,以及甚至不是来自@csv)jq -rj '.site[].equip + "," | [.] | @csv'
"Unique Item One,""Unique Item Two,""Unique Item Three,"
我尝试过的其他方法导致前导逗号,或者递归地连接和字符串化每个对象,但我得出的结论是我从根本上看是错误的。
如果我引入外部输入进行测试,(在这种情况下传递--arg) 使用 赋值运算符 ,我可以足够接近期望的结果以进一步取得进展,但它仍然为每个结果生成一行,并且变得非常不灵活:
jq -c --arg new2 "Unique Item Two" --arg new3 "Unique Item Three" -r '.site[] |= .equip + "," + $new2 + "," + $new3 |添加| .[] | tojson'
"Unique Item One,Unique Item Two,Unique Item Three"
现在我不确定我是否遗漏了一些简单的东西,或者这是否需要一些复杂的计数和迭代。
注意:我知道从外部切断输出是多么容易 - 有某些原因我想完全在 jq,因为它确实是我想要正确的结构。
您可以将它们分组以确定需要组合哪些 equip
值,然后您可以构建您的字符串。
$ jq -n --arg delim ',' '{
site: [inputs.site[]]
| group_by(.uuid)
| map({
uuid: .[0].uuid,
testtype: .[0].testtype,
name: .[0].name,
equip: (map(.equip | tojson) | unique | join($delim))
})
}' input.json
这会产生:(注意:不一定保留项目顺序)
{
"site": [
{
"uuid": "23451fae-a14f-49d1-a096-8f033f69dc80",
"testtype": "Scheduled",
"name": "JANE DOE HEAD OFFICE",
"equip": "\"Unique Item One\",\"Unique Item Two\",\"Unique Item Three\""
}
]
}
如果字符串看起来像 csv 数据并且需要转义,请务必这样做。假设引号需要转义,你可以修改这部分:
map(.equip | gsub("\"";"\"\"") | tojson)