Home > Net >  bash - jq how to parse brackets one by one
bash - jq how to parse brackets one by one

Time:05-18

a little stumped here. Definitely not an expert in bash scripting nor jq

What I'm trying to do currently, is, between both environments, check that mainAccount and secondAccount match. Meaning, in testing environment, I want to check if mainAccount = secondAccount, and same in production environment.

Where I'm running into issues, is parsing this json:

{
"file_version": 1.0,
"config": [
    {
        "environment": "testing",
        "main": [
            {
                "mainAccount": "123"
            }
        ],
        "second": [
            {
                "secondAccount": "456"
            }
        ]
    },
    {
        "environment": "production",
        "main": [
            {
                "mainAccount": "789"
            }
        ],
        "second": [
            {
                "secondAccount": "789"
            }
        ]
    }
]

}

with jq.

If I run this command:

jq -r '.config[] | select(.main != null) | .main[].mainAccount

My output is

123
789

If i store this output in a variable, it'll be 123 789 so comparing this to the "secondAccount" value is troublesome.

I think what I'm looking for is iteration here, however, I'm not sure how to implement this. I wanted to take a pythonic approach to check the length of the config array, create a for loop in that length range, then collect the value based on an index like

.config[0] | select(.main != null) | .main[].mainAccount
.config[1] | select(.main != null) | .main[].mainAccount

etc. The issue however, is that when I read in the .config[] value as a variable, bash doesn't interpret it like that. The length will be the length of characters, not, the amount of objects in the array.

Any thoughts on how to tackle this seemingly simple issue? I hope I was clear. Thanks!

CodePudding user response:

Given your input you can try this jq:

jq '
    .config[]
    | {
        environment,
        condition: (.main[0].mainAccount == .second[0].secondAccount)
    }' input.json

The result is:

{
  "environment": "testing",
  "condition": false
}
{
  "environment": "production",
  "condition": true
}

Some questions though:

  • Why are the values of first and second arrays objects and not object?
  • Is it really intended to match the first one of both?
  • Can there be more items in the arrays?

Also: If you want to process the results in a shell, I propose this expression because the output can be used (source or eval) in a shell:

jq -r '
    .config[]
    | "\(.environment)=\(.main[0].mainAccount == .second[0].secondAccount)"' input.json

The output is:

testing=false
production=true

CodePudding user response:

You can do the comparison within jq, return the boolean result as its exit status using the -e option, and react upon that in bash, e.g. using an if statement.

if jq -e '
  .config | map(select(.main != null) | .main[].mainAccount) | .[0] == .[1]
' file.json >/dev/null
then echo "equal"
else echo "not equal"
fi
not equal
  • Related