Home > Software engineering >  Set a value for an element found with select() but return the whole json
Set a value for an element found with select() but return the whole json

Time:12-04

I have a JSON like this:

{
  "name": "com.company1.package1",
  "version": "0.2",
  "dependencies": {
    "com.company1.package2": "0.1",
    "com.company2.package1": "2.3"
  }
}

And I want to change all dependencies with keys starting with "com.company1" to "0.2".

I managed to change it with this:

jq '.dependencies | with_entries(select(.key|startswith("com.company1"))) | .[]="0.2"'

But this only returns

{
  "com.company1.package2": "0.2"
}

I would like to get the whole initial JSON with only this value changed. How could go about that?

CodePudding user response:

You were almost there. Use the update operator |= and inside the update a direct assignment .value = "0.2".

jq '.dependencies |= with_entries(select(.key | startswith("com.company1")).value = "0.2")'
{
  "name": "com.company1.package1",
  "version": "0.2",
  "dependencies": {
    "com.company1.package2": "0.2",
    "com.company2.package1": "2.3"
  }
}

Demo

CodePudding user response:

You're projecting to a filtered view of your object (with all the | in your filter). Since you just want to do assignments, make sure that is at the top of your filter. select the properties you want to adjust then do the assignment.

It'll be easier if you used paths to do this, since you're filtering based on the path.

setpath(path(.dependencies[]) | select(.[1] | startswith("com.company1")); "0.2")

which produces:

{
  "name": "com.company1.package1",
  "version": "0.2",
  "dependencies": {
    "com.company1.package2": "0.2",
    "com.company2.package1": "2.3"
  }
}

jqplay

  • Related