I tried to use bash to run the following script:
#!/bin/bash
myvar="data1"
data='[
{
"resource_name": "data1.something",
"resource_type": "Topic"
},
{
"resource_name": "data2.something",
"resource_type": "Topic"
}
]'
query=$(echo ".[] | select((.resource_type==\"Topic\") and (.resource_name | startswith(\"${myvar}\") | not))")
echo ${data} | jq ${query}
It doesn't work becasue of line :
echo ${data} | jq ${query}
But if I run the same script in zsh, it works. and gives me the following error:
jq: error: Could not open file |: No such file or directory
jq: error: Could not open file select((.resource_type=="Topic"): No such file or directory
jq: error: Could not open file and: No such file or directory
jq: error: Could not open file (.resource_name: No such file or directory
jq: error: Could not open file |: No such file or directory
jq: error: Could not open file startswith("data1"): No such file or directory
jq: error: Could not open file |: No such file or directory
jq: error: Could not open file not)): No such file or directory
I was unable to understand what exactly is the issue here, I can only think that I somehow need to add single quotes when using with bash.
For example, if I use single quotes:
echo ${data} | jq \'${query}\'
it gives an error:
jq: error: syntax error, unexpected INVALID_CHARACTER, expecting $end (Unix shell quoting issues?) at <top-level>, line 1:
'.[] jq: 1 compile error
CodePudding user response:
Using the --arg
option to import content as variables is preferred over injecting shell variables into the actual filter code. This also saves you from dealing with single or double quotes.
#!/bin/bash
myvar="data1"
data='[
{
"resource_name": "data1.something",
"resource_type": "Topic"
},
{
"resource_name": "data2.something",
"resource_type": "Topic"
}
]'
query='.[] | select((.resource_type==$type) and (.resource_name | startswith($var) | not))'
echo "${data}" | jq --arg type "Topic" --arg var "${myvar}" "${query}"
{
"resource_name": "data2.something",
"resource_type": "Topic"
}