jq:如何将不相交的对象值组合为键/值对的单个对象?

时间:2018-03-30 10:57:16

标签: json jq

如果我有一个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"
}

有任何想法如何正确地做到这一点?

2 个答案:

答案 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"
}