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

Ste*_*ige 2 json jq

如果我有一个 JSON 输入数据:

输入.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"
   }
}
Run Code Online (Sandbox Code Playgroud)

我想从中创建以下内容:

{
  "first": "07f90eed-105d-41b2-bc20-4c20dfb51653",
  "second": "da187e3a-8db9-49fd-8c05-41f29cf87f51",
  "third": "6685c3af-5427-4add-8764-7b18ae3c23bb"
}
Run Code Online (Sandbox Code Playgroud)

也就是说,输入数据是一组单独的 JSON 对象,每个对象都具有所示的结构。我希望输出是单个 JSON 对象,其中键是.entity.name,值是.metadata.guid

我试过了:

jq -r '{.entity.name: .metadata.guid}' input.json
jq -r 'map({(.entity.name): .metadata.guid})' input.json
Run Code Online (Sandbox Code Playgroud)

但这些只会产生语法错误。我得到的最接近的是:

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"
}
Run Code Online (Sandbox Code Playgroud)

但是,仍然有 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"
}
Run Code Online (Sandbox Code Playgroud)

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

Rom*_*est 5

使用单个jq命令:

jq -s '[.[] | { (.entity.name): .metadata.guid }] | add' input.json
Run Code Online (Sandbox Code Playgroud)
  • -s( --slurp) - 不是为输入中的每个 JSON 对象运行过滤器,而是将整个输入流读入一个大数组并只运行一次过滤器。

输出:

{
  "first": "07f90eed-105d-41b2-bc20-4c20dfb51653",
  "second": "da187e3a-8db9-49fd-8c05-41f29cf87f51",
  "third": "6685c3af-5427-4add-8764-7b18ae3c23bb"
}
Run Code Online (Sandbox Code Playgroud)