Search code examples
jsonjmespath

JMESPath join output and strip unwanted chars


I have the following json;

[
  {
    "compartment-id": "CompartmentID-123",
    "defined-tags": {},
    "display-name": "Test-123",
    "freeform-tags": {},
    "id": "ID-ABC",
    "kms-key-id": "",
    "lifecycle-state": "ACTIVE",
  }
]

I am looking to join the id and display-name params into a comma seperate string with " and [] stripped, like so:

ID-ABC,Test-123

Closest I've managed to get so far is:

oci fs file-system list -c $compart --availability-domain $ad --query 'data[].[id,"display-name"][]' | tr -d '" '
[
ID-ABC,
Test-123
]

Wondering if there's a cleaner way of doing this all within JMESPath without piping output to tr, jq, sed or awk etc etc

UPDATE based on input from β.εηοιτ.βε

So close...

oci fs file-system list -c $compart --availability-domain $ad3 --query 'data[0].join(',', [id, "display-name"])'

Returns

ParseError: invalid token: Parse error at column 13, token "," (COMMA), for expression:
"data[0].join(,, [id, "display-name"])"

However playing around with quotes, best I can get is by using;

oci fs file-system list -c $compart --availability-domain $ad3 --query "data[0].join(',', [id, 'display-name'])"
Private key passphrase:
"ID-ABC,display-name"

I'm beginning to wonder if there's something wrong with my local settings or shell, whereby it's getting confused by the quotes marks?


Solution

  • Since you do have an array, you will first need to target the first element of the array, to get rid of it. Since an array is 0-based, this can easily be achieved via:

    data[0]
    

    which gives

    {
      "compartment-id": "CompartmentID-123",
      "defined-tags": {},
      "display-name": "Test-123",
      "freeform-tags": {},
      "id": "ID-ABC",
      "kms-key-id": "",
      "lifecycle-state": "ACTIVE"
    }
    

    Then, in order to create the string you are looking for, you can use the join function, that accepts, as parameter, a glue character and array.

    You can get the array you look for pretty easily, using filters and multiselect lists:

    data[0].[id, "display-name"]
    

    which gives

    [
      "ID-ABC",
      "Test-123"
    ]
    

    Now we just need to apply the join function on top of all this:

    data[0].join(',', [id, "display-name"])
    

    which finally gives:

    "ID-ABC,Test-123"
    

    Additional notes on quoting in JMESPath:

    So:

    data[0].join(',', [id, "display-name"])
    

    and

    data[0].join(`,`, [id, "display-name"])
    

    are two strictly equals queries.

    While

    data[0].join(',', [id, 'display-name'])
    

    has a totally different meaning and would end you with the string display-name being the second element of your array, so it will result in

    "ID-ABC,display-name"
    

    All of this based on the JSON structure:

    {
       "data":[
          {
             "compartment-id":"CompartmentID-123",
             "defined-tags":{},
             "display-name":"Test-123",
             "freeform-tags":{},
             "id":"ID-ABC",
             "kms-key-id":"",
             "lifecycle-state":"ACTIVE"
          }
       ]
    }