Here’s the json I need to parse:
{"protocol-config":[ {"protocol":"p1","config-var1":"vc1", "config-var2":"vc2"}, {"protocol":"p2","config-var1":"vc3", "config-var2":"vc4"} ]}
And my code to parse is like the following:
declare -a vals=("var1" "var2") for val in "${vals[@]}"; then eval "result=($(cat $INPUT | jq -r --arg i "$i" --arg var "config-$val" '.protocol-config[$i | tonumber][$var]'))" done
The problem is this part:
jq -r --arg i "$i" --arg var "config-$val" '.protocol-config[$i | tonumber][$var]'
I can’t get the value of it and I guess the reason is that I didn’t pass $var correctly? I also tried
jq -r --arg i "$i" --arg var "config-$val" '.protocol-config[$i | tonumber]["$var"]'
But it doesn’t work..Maybe the tiny ‘-‘ in the “config-$val” made it special? So my question is what is the right way to pass in argument like “config-$val” in jq?
Any help is appreciated! Thanks very much!
Advertisement
Answer
Your command fails not because you’re looping wrong or passing arguments wrong, but because protocol-config
is not a valid identifier:
$ jq '.protocol-config' error: config is not defined
The first step should always be to find a command that works without a loop or variables. Don’t try to write a loop for something you can’t get to run once! Don’t generalize a command you can’t get to work in a specific case!
Here’s a working command to get config-var1
from index 0
.
$ jq -r '.["protocol-config"][0]["config-var1"]' < json vc1
Now we can try to abstract out the arguments, testing to make sure it still works:
$ jq -r --arg i "0" --arg var "config-var1" '.["protocol-config"][$i|tonumber][$var]' < json vc1
Now that we have a working way of getting single items, we can do that multiple times with a loop:
$ cat myscript i=0 file="json" for var in "var1" "var2" do jq -r --arg i "$i" --arg var "config-$var" '.["protocol-config"][$i|tonumber][$var]' < "$file" done $ bash myscript vc1 vc2