Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Replace part of the value of a json using regex and jq

I have a json like bellow:

[
  {
    "name": "architecture-design-detailed",
    "rootPath": "/media/ismail/architecture-design-detailed/_Working/_NotesFiltered/_software/architecture-design-detailed",
    "paths": [],
    "group": "",
    "enabled": true
  },
  {
    "name": "architecture-design-detailed-engineering",
    "rootPath": "/media/ismail/architecture-design-detailed/_Working/_NotesFiltered/_software/architecture-design-detailed-engineering",
    "paths": [],
    "group": "",
    "enabled": true
  }
]

If name is architecture-design-detailed,

  • change name to new_name_here

    MEDevel.com: Open-source for Healthcare and Education

    Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

    Visit Medevel

  • replace last part of rootPath (which is architecture-design-detailed, after the last /) with new_name_here.

So the expected output is:

[
  {
    "name": "new_name_here",
    "rootPath": "/media/ismail/architecture-design-detailed/_Working/_NotesFiltered/_software/new_name_here",
    "paths": [],
    "group": "",
    "enabled": true
  },
  {
    "name": "architecture-design-detailed-engineering",
    "rootPath": "/media/ismail/architecture-design-detailed/_Working/_NotesFiltered/_software/architecture-design-detailed-engineering",
    "paths": [],
    "group": "",
    "enabled": true
  }
]

What I came up with so far is:

jq 'map(if .name == "architecture-design-detailed" then .name = "new_name_here" else . end)'

But not understanding how to replace last part of rootPath. I think we have to use sub or gsub. But not understanding how.

>Solution :

You can use split("/") to convert rootPath to an array, then set the last index (.[-1]) to new_name and then join("/") them back together.

We use |= inside map() to just update those objects found by select() and then overwrite .name and rootPath as needed.

map(select(.name == "architecture-design-detailed") 
    |= ( 
        .name = "new_name",
        .rootPath = (.rootPath | split("/") | .[-1] = "new_name" | join("/"))
    ) 
)
[
  {
    "name": "new_name",
    "rootPath": "/media/ismail/architecture-design-detailed/_Working/_NotesFiltered/_software/new_name",
    "paths": [],
    "group": "",
    "enabled": true
  },
  {
    "name": "architecture-design-detailed-engineering",
    "rootPath": "/media/ismail/architecture-design-detailed/_Working/_NotesFiltered/_software/architecture-design-detailed-engineering",
    "paths": [],
    "group": "",
    "enabled": true
  }
]

JqPlay Demo

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading