jsonjq

Extract dictionaries from JSON where a field value starts with a certain string


I'm trying to parse this json so that I can extract all dictionaries from the input where the "uri" field does not start with the string "/themes"

  {
    "version": 0,
    "permissionMask": 2,
    "creationDate": "2022-06-09T14:42:41",
    "updateDate": "2021-11-17T06:48:52",
    "label": "webPageView.css",
    "uri": "/themes/default/webPageView.css",
    "resourceType": "file"
  },
  {
    "version": 0,
    "permissionMask": 2,
    "creationDate": "2022-06-09T14:42:43",
    "updateDate": "2021-11-17T06:48:48",
    "label": "workflow_icons_sprite@05x.png",
    "uri": "/internal/default/images/workflow_icons_sprite@05x.png",
    "resourceType": "file"
  }

so the output would only contain

  {
    "version": 0,
    "permissionMask": 2,
    "creationDate": "2022-06-09T14:42:43",
    "updateDate": "2021-11-17T06:48:48",
    "label": "workflow_icons_sprite@05x.png",
    "uri": "/internal/default/images/workflow_icons_sprite@05x.png",
    "resourceType": "file"
  }

I've tried

jq -r '.[] | select( .[].uri | ( startswith( "/themes" ) | not ) )'

but that doesn't seem to work. It simply dumps all the output without filtering out the dictionaries where the uri field starts with "/themes"


Solution

  • Assuming that the objects are in an array

    .[] | select(.uri | startswith( "/themes" ) | not)
    

    Gives

    {
      "version": 0,
      "permissionMask": 2,
      "creationDate": "2022-06-09T14:42:43",
      "updateDate": "2021-11-17T06:48:48",
      "label": "workflow_icons_sprite@05x.png",
      "uri": "/internal/default/images/workflow_icons_sprite@05x.png",
      "resourceType": "file"
    }
    
    Try it online

    Regarding your filter, there's no need for the .[].uri inside select() since the first .[] already loops over the array, so . inside the select() refers to the object itself.