问题
I'm working on a script for my openwrt, a watchdog for my pia connection. I'm trying to make this little jq filter but every time I try I get error I've more options and I "compose" the jq filter
all_region_data=$(curl -s "https://serverlist.piaservers.net/vpninfo/servers/v4" | head -1)
BestRegion="italy"
jq_filter='.regions[]'
if [ -z "$BestRegion" ]; then # BestRegion not forced
if [ "$pia_pf" = "true" ]; then
jq_filter="${jq_filter} | select(.port_forward==true)"
fi
if [ "$pia_no_geo" = "false" ]; then
jq_filter="${jq_filter} | select(.geo==false)"
fi
if [ "$pia_no_geo" = "true" ]; then
jq_filter="${jq_filter} | select(.geo==true)"
fi
jq_filter="${jq_filter} | .servers.meta[0].ip+\" \"+.id+\" \"+.name+\" \"+(.geo|tostring)"
summarized_region_data=$(echo "$all_region_data" | jq -r "${jq_filter}")
best_region # function to extract best_region
if [ -z "$BestRegion" ]; then
log "..."
log "No region responded within ${max_latency}s, consider using a higher timeout."
rm -rf "$wg_script_lock_file"
return
fi
else # BestRegion forced
if [ "$pia_pf" = "true" ]; then
jq_filter="${jq_filter} | select(.port_forward==true)"
fi
if [ "$pia_no_geo" = "false" ]; then
jq_filter="${jq_filter} | select(.geo==false)"
fi
if [ "$pia_no_geo" = "true" ]; then
jq_filter="${jq_filter} | select(.geo==true)"
fi
fi
The first if cycle
works, the function do the dirty works. But I want to have the opportunity to "force" the BestRegion
so I created the else cycle
. Here I've the problem!
This's what I'm trying to do
echo $all_region_data | jq --arg REGION_ID "$BestRegion" --arg JQ_FILTER "$jq_filter" -r '$JQ_FILTER | select(.id==$REGION_ID)'
I can't use these two var
, I get this error
jq: error (at <stdin>:1): Cannot index string with string "id"
How would you do it?
回答1:
If I understand you correctly, the problem you're looking for help with is this:
You have a shell variable $jq_filter
that contains the text of a JQ filter. You have a shell variable $BestRegion
that contains a plain text string. You want to pass the former in as part of a larger JQ filter while passing the latter in as a JQ variable.
Try:
jq --arg REGION_ID "$BestRegion" "$jq_filter"'| select(.id==$REGION_ID)'
Specifically, you want the shell to expand $jq_filter
before passing it to JQ, so you put it in double quotes, but you want JQ to process $REGION_ID
so you keep it in single quotes. Note that there is no space between the double quote and the single quote - this ensures the shell combines both strings together as one argument to JQ.
来源:https://stackoverflow.com/questions/64937500/jq-1-5-multiple-bash-variables-as-argument