Saturday, April 9, 2022

[SOLVED] Multiple `if` conditions with `jq` and `grep` incorrectly matches and returns true when it shouldn't match at all

Issue

I have a json file:

cat myjsonfile.json

{
    "directory": true,
    "condition": "",
    "specialCondition": "",
    "dataFiles": "",
    "nonstandard-protocol": true
}

specialCondition is standardized and can be empty or have a matched or unmatched state.

I simply want to translate those conditions to another state when nonstandard-protocol is false.

So I wrote this in my bash script.

if [[  "jq '.specialCondition' myjsonfile.json | grep -q 'matched'"  &&  "jq '."nonstandard-protocol"' myjsonfile.json | grep -q 'false'"  ]]; then echo 'MATCHED' | cat > protocol_result.txt; fi
if [[  "jq '.specialCondition' myjsonfile.json | grep -q 'unmatched'"  &&  "jq '."nonstandard-protocol"' myjsonfile.json | grep -q 'false'"  ]]; then echo 'NOTMATCHED' | cat > protocol_result.txt; fi

However, this returns incorrect results. When I run the script, I always see that first it writes MATCHED to my protocol_result.txt and then with the second if line it writes NOTMATCHED to the file! While it shouldn't write anything at all... Why is this happening?


Solution

Take the if statements to jq and have it output whatever you want.

The following example prints nothing "" if nonstandard-protocol is true, or specialCondition is neither matched nor unmatched. Otherwise it'll print MATCHED or NOTMATCHED, depending on the content of specialCondition:

jq --raw-output '
  if ."nonstandard-protocol" then ""
  else if .specialCondition == "matched" then "MATCHED"
    elif .specialCondition == "unmatched" then "NOTMATCHED"
    else "" end
  end
' myjsonfile.json > protocol_result.txt

Demo

Note: Using "" will print nothing as expected, but followed by a newline because it had an output (which essentially is an empty line, then). If you don't want that, change "" to empty.



Answered By - pmf
Answer Checked By - Dawn Plyler (WPSolving Volunteer)