Albert
Albert

Reputation: 507

jq: extract a specific key from one object to another

I have two JSON files.

file1.json:

{
  "Fruits": [
  {
    "name": "Apple",
    "something_else": 123,
    "id": 652090
  },
  {
    "name": "Orange",
    "something_else": 456,
    "id": 28748
  }
]}

file2.json:

{
  "Fruits": [
  {
    "weight": 5,
    "id": 652090
  },
  {
    "weight": 7,
    "id": 28748
  }
]}

I want to combine objects from both files if they have a common key 'id', but to extract only 'name' property from file1. How do I do that using jq?

This is what I want to get:

{
  "Fruits": [
  {
    "name": "Apple",
    "weight": 5,
    "id": 652090
  },
  {
    "name": "Orange",
    "weight": 7,
    "id": 28748
  },
]}

Upvotes: 0

Views: 436

Answers (2)

Jeff Mercado
Jeff Mercado

Reputation: 134571

There's plenty of ways this could be constructed. Here's another way:

$ jq '.Fruits |= (. + input.Fruits | [group_by(.id)[] | add | {name,weight,id}])' \
file1.json file2.json
{
  "Fruits": [
    {
      "name": "Orange",
      "weight": 7,
      "id": 28748
    },
    {
      "name": "Apple",
      "weight": 5,
      "id": 652090
    }
  ]
}

Upvotes: 1

oguz ismail
oguz ismail

Reputation: 50795

Combine Fruits arrays, group it by id, select groups with 2 elements because we want fruits present in both files. For each selected group; add name field from first group element to second, and collect results in an array.

jq -n '[inputs.Fruits[]]
| reduce (group_by(.id)[] | select(length==2)) as $f
  ([]; . + [$f[1] + ($f[0] | {name})])' file1.json file2.json

Note that the order files are given on the command line is important, the file with names should be given before the other.


Combining objects with same id and extracting a subset of fields is way much easier though:

jq -n '[inputs.Fruits[]]
| group_by(.id)
| map(select(length==2) | add | {name, id, weight})
' file1.json file2.json

Upvotes: 1

Related Questions