Home > Enterprise >  Using Select to filter in jq query
Using Select to filter in jq query

Time:11-10

previously I posted a question here (Create a list from json file, with multiple values). However, I found some of my keys are outdated, and they contain a key called "end". I was not able to filter them out, making the data erratic.

Here's the updated JSON that I use for testing:

[
  {
    "primary": "JOHN DOE",
    "attributes": [
      {
        "type": "double",
        "name": "BUILDING_NUMBER",
        "value": "123"
      },
      {
        "type": "double",
        "name": "FLOOR",
        "value": 10
      },
      {
        "type": "string",
        "name": "EMAIL",
        "value": "[email protected]"
      },
      {
        "type": "string",
        "name": "JOB_TITLE",
        "value": "SALESMAN"
      },
      {
        "type": "string",
        "name": "JOB_TITLE",
        "value": "TRAINEE",
        "end": "11-09-2022"
      }
    ],
    "aliases": [
      {
        "alias": "[email protected]"
      }
    ]
  },
  {
    "primary": "LORRAINE DOE",
    "attributes": [
      {
        "type": "double",
        "name": "BUILDING_NUMBER",
        "value": 456
      },
      {
        "type": "double",
        "name": "FLOOR",
        "value": 10
      },
      {
        "type": "string",
        "name": "STATUS",
        "value": "Unavaliable"
      },
      {
        "type": "string",
        "name": "EMAIL",
        "value": "[email protected]"
      },
      {
        "type": "string",
        "name": "JOB_TITLE",
        "value": "Procurement",
        "end": "11-09-2021"
      },
      {
        "type": "string",
        "name": "JOB_TITLE",
        "value": "SECRETARY"
      },
      {
        "type": "string",
        "name": "JOB_TITLE",
        "value": "SALES",
        "end": "11-09-2021"
      }
    ],
    "aliases": [
      {
        "alias": "[email protected]"
      },
      {
        "alias": "[email protected]"
      }
    ]
  },
  {
    "primary": "JACK DOE",
    "attributes": [
      {
        "type": "double",
        "name": "BUILDING_NUMBER",
        "value": "123"
      },
      {
        "type": "double",
        "name": "FLOOR",
        "value": 10
      },
      {
        "type": "string",
        "name": "JOB_TITLE",
        "value": "OWNER"
      }
    ],
    "aliases": [
      {
        "alias": "[email protected]"
      },
      {
        "alias": "[email protected]"
      }
    ]
  },
  {
    "primary": "NOAH DOE",
    "attributes": [
      {
        "type": "double",
        "name": "BUILDING_NUMBER",
        "value": "123"
      },
      {
        "type": "double",
        "name": "FLOOR",
        "value": 10
      },
      {
        "type": "string",
        "name": "EMAIL",
        "value": "[email protected]"
      }
    ],
    "aliases": [
      {
        "alias": "[email protected]"
      }
    ]
  }
]

Is there a way to filter out the attributes with key "end" and make the result as below?

"[email protected]": "SALESMAN",
"[email protected]": "SECRETARY"

This is the old solution:

.[].attributes | from_entries
| select(has("JOB_TITLE") and has("EMAIL"))
| "\"\(.EMAIL)\": \"\(.JOB_TITLE)\""

CodePudding user response:

Filter them out using a map before running from_entries:

.[].attributes 
| map(select(.name != "JOB_TITLE" or (has("end") | not)))
| from_entries
| select(has("JOB_TITLE") and has("EMAIL"))
| "\"\(.EMAIL)\": \"\(.JOB_TITLE)\""
"[email protected]": "SALESMAN"
"[email protected]": "SECRETARY"

Demo

CodePudding user response:

Before converting the attributes to objects, select only those which do not have an end property:

.[].attributes
| map(select(has("end")|not)) # <- this line is new
| from_entries
| select(has("JOB_TITLE") and has("EMAIL"))
| "\"\(.EMAIL)\": \"\(.JOB_TITLE)\""

Output:

"[email protected]": "SALESMAN"
"[email protected]": "SECRETARY"
  • Related