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