Json 合并yaml文件并按键值列表的值重新组织
我有一个yaml文件列表,每个文件描述一个项目,其中包含一个代表可持续发展目标的数字列表 我希望合并所有文件并将它们转换为不同格式的json,sdg索引作为键,相关项目作为列表值 输入:Json 合并yaml文件并按键值列表的值重新组织,json,yaml,jq,Json,Yaml,Jq,我有一个yaml文件列表,每个文件描述一个项目,其中包含一个代表可持续发展目标的数字列表 我希望合并所有文件并将它们转换为不同格式的json,sdg索引作为键,相关项目作为列表值 输入: --- # gnu_health.yaml description: > GNU Health is a Free/Libre project for health practitioners, health institutions and governments. It provides th
---
# gnu_health.yaml
description: >
GNU Health is a Free/Libre project for health practitioners, health
institutions and governments. It provides the functionality of Electronic
Medical Record (EMR), Hospital Management (HMIS) and Health Information
System (HIS).
sdgs: [3]
name: GNU Health
---
# a11y.yaml
description: >
This Accessibility Project is a community-driven effort to make web
accessibility easier by leveraging a worldwide community of developer
knowledge.
sdgs: [10]
name: A11Y
---
# bahmni.yaml
description: >
Bahmni is an Open Source hospital Management System focusing
on poor/underserved and public hospitals in the developing
world.
It's aimed to being a generic system which can be used for
multiple diseases and hospitals in different countries.
sdgs: [1, 3]
name: Bahmni
预期产出:
{
"1": [
{
"name": "Bahmni",
"description: "..."
}
],
"3": [
{
"name": "GNU Health",
"description: "..."
},
{
"name": "Bahmni",
"description: "..."
}
],
"10": [
{
"name: "A11Y",
"description: "..."
}
]
}
{
"1": [
{
"name": "Bahmni",
"description: "..."
}
],
"3": [
{
"name": "GNU Health",
"description: "..."
}
],
"3": [
{
"name": "Bahmni",
"description: "..."
}
],
"10": [
{
"name: "A11Y",
"description: "..."
}
]
}
我发现使用jq的过滤系统很难解决这个问题,即使在阅读了文章和其他资源之后
有人能给我指一下正确的方向吗
目前的最大努力:
# use as follow: yq -f $binDir/concat_sdgs.jq $srcDir/*.y*ml
# concat_sdgs.jq
{
(.sdgs[]|tostring): [.]
}
不幸的是,这不会将来自同一sdg的项目合并在一起
当前输出不正确:
{
"1": [
{
"name": "Bahmni",
"description: "..."
}
],
"3": [
{
"name": "GNU Health",
"description: "..."
},
{
"name": "Bahmni",
"description: "..."
}
],
"10": [
{
"name: "A11Y",
"description: "..."
}
]
}
{
"1": [
{
"name": "Bahmni",
"description: "..."
}
],
"3": [
{
"name": "GNU Health",
"description: "..."
}
],
"3": [
{
"name": "Bahmni",
"description: "..."
}
],
"10": [
{
"name: "A11Y",
"description: "..."
}
]
}
好消息是你已经接近了 为了简单起见,我将假设.yaml到.json的转换已经完成。稍微调整一下过滤器,很容易看出:
jq '{ (.sdgs[]|tostring): del(.sdgs) }' a11y.json gnu_health.json bahmni.json
生成一个由四个单关键点对象组成的流,这些对象与所需对象密切对应
将它们组合成单个对象有点棘手。为了简单起见,让我们首先定义一个helper函数,该函数可用于按键对单个键对象进行分组:
def group_by_keys: reduce .[] as $o ({};
reduce ($o | to_entries[]) as $kv (.; .[$kv.key]
接下来,我们将使用带有-n命令行选项的输入
:
jq -n '
def group_by_keys: reduce .[] as $o ({};
reduce ($o | to_entries[]) as $kv (.; .[$kv.key] += [$kv.value]));
[inputs | {(.sdgs[]|tostring): del(.sdgs) }] | group_by_keys
' a11y.json gnu_health.json bahmni.json
(不要忘记-n
)
如果键的顺序很重要,则只需使用此过滤器:
def sort_by_keys:
to_entries
| sort_by(.key|tonumber)
| from_entries;
谢谢你的回复。不幸的是,这似乎没有产生预期的结果。我没有为每个sdg键创建一个项目列表,而是将一个项目视为sdg的对象值。如果我可以为每个sdg连接项目,这将是完美的,我正在做-n。它仍然只在输出中列出每个sdg的一个项目。如果您尝试使用3个文件运行此操作,其中2个文件具有
sdg:[3]
,则只会返回一个项目抱歉,我已使用更好的示例更新了此问题:)让我们开始调试。debug
是开始调试的好地方。我想你会发现花时间掌握reduce
和to_条目
过滤器家族是值得的。