skip to Main Content

I have the following JSON that comes back from an API:

{
"Statement": [{
        "Sid": "Group1",
        "Resource": "arn:aws:ecs:*:777744445555:task-rendition/${aws:PrincipalTag/Service}-*:*",
        "Effect": "Allow"
    },
    {
        "Sid": "Group2",
        "Resource": [
            "arn:aws:ecs:*:777744445555:task-definition/${aws:PrincipalTag/Service}-*:*",
            "arn:aws:ecs:*:777744445555:task-petition/${aws:PrincipalTag/Service}-*:*",
            "arn:aws:ecs:*:777744445555:task-fruition/${aws:PrincipalTag/Service}-*:*"
        ],
        "Effect": "Allow"
    }

]}

When I apply these commands I get unreliable results:

.Statement[0].Resource | length –> 73 incorrect
.Statement[1].Resource | length –> 3 correct

The first command produces the number equal to the number of characters in that string, which is not what I need. How can I achieve the 1 and 3 in a more certain way?

My context is bash shell script on CentOS 7 and jq 1.5

3

Answers


  1. Assuming Resource can either be of type string or array

    .Statement[].Resource | if type == "array" then length else 1 end
    

    will output

    1
    3
    
    Login or Signup to reply.
  2. You can convert the Resource section to an array, flatten() it, then pipe it out to length() to get the correct number of elements.

    $ cat api_return.json | jq '[.Statement[0].Resource] | flatten | length'
    1
    
    Login or Signup to reply.
  3. For the total count of resources, wherever they are specified, you might like to consider:

    def sigma(s): reduce s as $x (0; .+$x);
    
    sigma(.. | objects | select(.Resource).Resource
          | if type == "array" then length else 1 end)
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search