Home > OS >  Copying fields between array elements in JQ
Copying fields between array elements in JQ

Time:09-03

I'm relatively new to JQ and this might be a simple question.

I have a big, pretty nested JSON file with thousands of assets. Each asset always contains one array with two objects (one mother and one child).

{
  "data": [
    {
      "assets": {
        "array": [
          {
            "id": "7978918",
            "labels": {
              "text": "mother",
              "value": true
            },
            "properties": {
              "context_ids": [],
              "parent": null
            }
          },
          {
            "id": "caa17b2a-4582-4d13-b891-2607e4ba33c6",
            "labels": {
              "text": "child",
              "value": true
            },
            "properties": {
              "context_ids": [],
              "parent": null
            }
          }
        ]
      }
    }
  ]
}

What I want to do is copying the id from the mother object into the parent field of the child object.

{
  "data": [
    {
      "assets": {
        "array": [
          {
            "id": "7978918",
            "labels": {
              "text": "mother",
              "value": true
            },
            "properties": {
              "context_ids": [],
              "parent": null
            }
          },
          {
            "id": "caa17b2a-4582-4d13-b891-2607e4ba33c6",
            "labels": {
              "text": "child",
              "value": true
            },
            "properties": {
              "context_ids": [],
              "parent": "7978918"
            }
          }
        ]
      }
    }
  ]
}

So far I got

cat test.json | jq '.data[].assets.array[]|=(.properties.parent=.id|select(.labels.text=="mother"))' |less

but this, of course, only copies the mother id into the mother object's parent field and deletes the child object entirely.

I also tried

cat test.json | jq '.data[].assets.array[].properties  = {"parent": .data[].assets.array[0].id} |less

On first sight this looked to be correct but seemingly has created a strange loop which never stops and creates a bigger and bigger JSON.

CodePudding user response:

Assuming the first element is always the mother, this should work just fine:

.data[].assets.array |= (.[1].properties.parent = .[0].id)

Online demo

Otherwise sort them by labels.text first so that they are always at certain indices.

.data[].assets.array |= (sort_by(.labels.text) | .[0].properties.parent = .[1].id)

CodePudding user response:

jq '.data |= map(.assets.array | .[1].properties.parent = .[0].id)' test.json
  • Related