如果我有一个JSON输入数据:
input.json
{
"metadata": {
"guid": "07f90eed-105d-41b2-bc20-4c20dfb51653"
},
"entity": {
"name": "first"
}
}
{
"metadata": {
"guid": "da187e3a-8db9-49fd-8c05-41f29cf87f51"
},
"entity": {
"name": "second"
}
}
{
"metadata": {
"guid": "6685c3af-5427-4add-8764-7b18ae3c23bb"
},
"entity": {
"name": "third"
}
}
我想从中创建以下内容:
{
"first": "07f90eed-105d-41b2-bc20-4c20dfb51653",
"second": "da187e3a-8db9-49fd-8c05-41f29cf87f51",
"third": "6685c3af-5427-4add-8764-7b18ae3c23bb"
}
也就是说,输入数据是单独的JSON对象的集合,每个JSON对象都具有所示的结构。我希望输出是一个JSON对象,其中键是.entity.name
,值是.metadata.guid
。
我试过了:
jq -r '{.entity.name: .metadata.guid}' input.json
jq -r 'map({(.entity.name): .metadata.guid})' input.json
但这些只会产生语法错误。我得到的最接近的是:
jq -r '.entity.name as $name|.metadata.guid as $guid | { ($name) : ($guid) }' input.json
{
"first": "07f90eed-105d-41b2-bc20-4c20dfb51653"
}
{
"second": "da187e3a-8db9-49fd-8c05-41f29cf87f51"
}
{
"third": "6685c3af-5427-4add-8764-7b18ae3c23bb"
}
但是,仍有3个对象(不是1个)。
我确实得到了一张表格给了我想要的东西,但我怀疑有更简单的方法可以做到这一点:
jq -r '.entity.name as $name|.metadata.guid as $guid | { ($name) : ($guid) }' input.json | jq -s add
{
"first": "07f90eed-105d-41b2-bc20-4c20dfb51653",
"second": "da187e3a-8db9-49fd-8c05-41f29cf87f51",
"third": "6685c3af-5427-4add-8764-7b18ae3c23bb"
}
有任何想法如何正确地做到这一点?
答案 0 :(得分:3)
使用单个 jq
命令:
jq -s '[.[] | { (.entity.name): .metadata.guid }] | add' input.json
-s
(--slurp
) - 不是为输入中的每个JSON对象运行过滤器,而是将整个输入流读入一个大型数组并仅运行一次过滤器。输出:
{
"first": "07f90eed-105d-41b2-bc20-4c20dfb51653",
"second": "da187e3a-8db9-49fd-8c05-41f29cf87f51",
"third": "6685c3af-5427-4add-8764-7b18ae3c23bb"
}
答案 1 :(得分:1)
获得三个对象的简单方法是jq '{(.entity.name): .metadata.guid}' input.json
。
将密钥(.entity.name
)括在括号中会将jq
告诉evaluate it as an expression,而不是字符串。
这会导致您已经拥有的更简单的形式(使用jq
的两次调用):
$ jq '{(.entity.name): .metadata.guid}' input.json | jq -s add
{
"first": "07f90eed-105d-41b2-bc20-4c20dfb51653",
"second": "da187e3a-8db9-49fd-8c05-41f29cf87f51",
"third": "6685c3af-5427-4add-8764-7b18ae3c23bb"
}