0

I have a system that outputs multiple types of JSON files with data.

Is there any chance to implement the three conditions below using jq? I am exploring the map() command, and the --arg and --argjson command line options, but I am having a tough time.

First JSON, where I have an asset object and I want to add following key-value pair:

"house": true and "colour": "orange"

{
    "name": "Paul",
    "country": "USA",
    "spec": {
        ...
        "asset": {
            "yard": true
        },        
    }    
}

Desired output:

{
    "name": "Paul",
    "country": "USA",
    "spec": {
        ...
        "asset": {
            "house": true,
            "colour": "orange",
            "yard": true
        },        
    }    
}

2nd JSON, where I don't have an asset object, so I want to add the object and the following key-value pair

"house": true and "colour": "orange"

{
    "name": "Paul",
    "country": "USA",
    "spec": {
        ...
    }    
}

Desired output:

{
    "name": "Paul",
    "country": "USA",
    "spec": {
        ...
        "asset": {
            "house": true,
            "colour": "orange"
        },        
    }    
}

3rd JSON, where I have an asset object, but I would like to change the key-value pair of house if it is set to false and set colour to orange:

{
    "name": "Paul",
    "country": "USA",
    "spec": {
        ...
        "asset": {
            "house": false,
            "colour": "black"
        },        
    }    
}

Desired output:

{
    "name": "Paul",
    "country": "USA",
    "spec": {
        ...
        "asset": {
            "house": true,
            "colour": "orange"
        },        
    }    
}
0

1 Answer 1

1

The following takes the colour as a string from the command line using --arg and the boolean using --argjson (since it's not a string). It then unconditionally sets the colour and house keys inside .spec.asset to these given values. If .spec.asset does not exist in the input document, it is created.

jq --arg colour orange --argjson house true '.spec.asset += $ARGS.named' input.json

The $ARGS.named variable in jq is an object containing the named arguments as keys, with the given arguments as values. In the example above, $ARGS.named would be the equivalent of

{"colour":"orange","house":true}

Adding this with += to the part of the document that we want to modify has the effect of adding the given keys and values of that part, overwriting keys that already exists.

Running the command on each of the input files:

$ jq . -c file1
{"name":"Paul","country":"USA","spec":{"asset":{"yard":true}}}
$ jq --arg colour orange --argjson house true '.spec.asset += $ARGS.named' file1
{
  "name": "Paul",
  "country": "USA",
  "spec": {
    "asset": {
      "yard": true,
      "colour": "orange",
      "house": true
    }
  }
}
$ jq . -c file2
{"name":"Paul","country":"USA","spec":{}}
$ jq --arg colour orange --argjson house true '.spec.asset += $ARGS.named' file2
{
  "name": "Paul",
  "country": "USA",
  "spec": {
    "asset": {
      "colour": "orange",
      "house": true
    }
  }
}
$ jq . -c file3
{"name":"Paul","country":"USA","spec":{"asset":{"house":false,"colour":"black"}}}
$ jq --arg colour orange --argjson house true '.spec.asset += $ARGS.named' file3
{
  "name": "Paul",
  "country": "USA",
  "spec": {
    "asset": {
      "house": true,
      "colour": "orange"
    }
  }
}
2
  • I believed i made mistake explaining the 2nd scenario. Basically what I am trying to do is - If there is no asset object -> Create asset object, put house set to true and colour ornage in the element. If there is asset object already -> check if house is set to something else AND check colour is SET to something else, if that is the case then set hosue back to true and colour to orange. If there is asset class already in place, but house and colour key is not present in the object, then add house to true and colour to orange. Hope that clarifies. Sep 1, 2023 at 2:05
  • @infotechsups The answer is updated.
    – Kusalananda
    Sep 1, 2023 at 6:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .