skip to Main Content

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

  • 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.

3

Answers


  1. 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

    Login or Signup to reply.
  2. To achieve your goal with jq, you indeed need to use the sub function to replace the last part of rootPath when name matches "architecture-design-detailed". Your jq filter needs to be expanded to also conditionally modify rootPath in addition to changing name.

    map(
      if .name == "architecture-design-detailed" then
        .name = "new_name_here" |
        .rootPath |= sub("/architecture-design-detailed$"; "/new_name_here")
      else
        .
      end
    )
    

    Output:

    [
      {
        "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
      }
    

    ]

    Login or Signup to reply.
  3. Here’s another approach that updates at once the two fields .name, .rootPath for selected items matching .name == $from by right-trimming by the old name using rtrimstr($from), and then adding the new one with + $to:

    jq --arg from 'architecture-design-detailed' --arg to 'new_name_here' '
      map((select(.name == $from) | .name, .rootPath) |= rtrimstr($from) + $to)
    '
    
    [
      {
        "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
      }
    ]
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search