【问题标题】:jq 1.5 multiple bash variables as argumentjq 1.5 多个 bash 变量作为参数
【发布时间】:2021-03-04 08:14:18
【问题描述】:

我正在为我的 openwrt 编写脚本,它是我的 pia 连接的看门狗。我正在尝试制作这个小 jq 过滤器,但每次尝试时都会出错 我有更多选择,我“编写”了 jq 过滤器

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

第一个if cycle 工作,函数做脏工作。但我想有机会“强制”BestRegion,所以我创建了else cycle。问题来了!

这就是我想要做的事情

echo $all_region_data | jq --arg REGION_ID "$BestRegion" --arg JQ_FILTER "$jq_filter" -r '$JQ_FILTER | select(.id==$REGION_ID)'

我不能使用这两个var,我得到这个错误

jq: error (at <stdin>:1): Cannot index string with string "id"

你会怎么做?

【问题讨论】:

  • 调用jq --arg REGION_ID "$BestRegion" --arg JQ_FILTER "$jq_filter" -r $JQ_FILTER | select(.id==$REGION_ID)' 相当混乱。密切注意shell变量和jq变量的区别。并且不要忘记,如果您在 shell 中设置 X=.a,那么 jq --arg x "$X" '$x' 将打印 JSON 字符串 ".a"
  • 我可以对变量重新排序,以便将第一个 arg 设置为 jq_filter,第二个设置为 region_id。我还可以更改 var 名称以确保不会犯任何错误。如果我只使用一个 arg 但我需要两个,那么一切正常。我需要一个非 JSON 输出,所以我在 jq 中使用了-r 选项,我认为是对的。我认为问题出在"' 上,但我不知道如何处理,我尝试了很多变体但没有运气

标签: sh posix jq


【解决方案1】:

如果我的理解正确,您正在寻求帮助的问题是:

您有一个 shell 变量 $jq_filter,其中包含 JQ 过滤器的文本。您有一个包含纯文本字符串的 shell 变量 $BestRegion。您希望将前者作为较大 JQ 过滤器的一部分传入,而将后者作为 JQ 变量传入。

试试:

jq --arg REGION_ID "$BestRegion" "$jq_filter"'| select(.id==$REGION_ID)'

具体来说,您希望 shell 在将 $jq_filter 传递给 JQ 之前对其进行扩展,因此您将其放在双引号中,但您希望 JQ 处理 @987654325 @ 所以你把它放在单引号中。请注意,双引号和单引号之间没有空格 - 这可以确保 shell 将两个字符串组合在一起作为 JQ 的一个参数。

【讨论】:

  • 是的,在我的 bash 脚本中,我想传递 2 个变量,jq_filter 包含从各种选项“构建”的整个过滤器和包含纯文本的 BestRegion。我的第一个想法是通过 2 arg 但我遇到了扩展问题。如果需要,我可以修改 vars 的单/双引号,但我会试试这个
猜你喜欢
  • 1970-01-01
  • 2021-09-29
  • 2018-12-27
  • 2018-02-26
  • 2015-12-26
  • 2018-05-25
  • 2014-04-21
  • 1970-01-01
相关资源
最近更新 更多