【问题标题】:jq in shellscript: parse argument with '-'shell脚本中的jq:用'-'解析参数
【发布时间】:2015-05-18 23:04:07
【问题描述】:

这是我需要解析的json:

{"protocol-config":[
    {"protocol":"p1","config-var1":"vc1", "config-var2":"vc2"},
    {"protocol":"p2","config-var1":"vc3", "config-var2":"vc4"}
]}

我要解析的代码如下:

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

问题出在这部分:

jq -r --arg i "$i" --arg var "config-$val" '.protocol-config[$i | tonumber][$var]'

我无法得到它的值,我猜是因为我没有正确传递 $var?我也试过了

jq -r --arg i "$i" --arg var "config-$val" '.protocol-config[$i | tonumber][\"$var\"]'

但它不起作用..也许“config-$val”中的小“-”让它变得特别?所以我的问题是在 jq 中传递像“config-$val”这样的参数的正确方法是什么?

感谢任何帮助!非常感谢!

【问题讨论】:

  • 您能否包括实际和预期的输出,而不是仅仅说“但它不起作用”?这段代码也有看似无关的问题:使用then而不是do,没有定义$i,混合$REPLY$input。你能先解决这些吗? (记住永远不要在运行和发布之间修改代码。修改应该总是在运行之前发生,这样发布的代码和结果是同步的)
  • 你把它弄得太复杂了。您要提取哪些值?我很确定它可以是一个班轮。
  • 嗨 @hek2mgl 我需要提取 config-var1 和 config-var2。问题是,也许以后我需要提取 config2-var1, config2-var2, config3-var1, config3-var2 等,目前不存在。总而言之,'*-var1' 和 '*-var2'。
  • 如果你只是想在 jq 命令中注入一个变量,使用这样的东西:i=1; jq ".foobar$i" test.json

标签: json linux bash shell jq


【解决方案1】:

您的命令失败不是因为您循环错误或传递参数错误,而是因为protocol-config 不是有效标识符:

$ jq '.protocol-config'
error: config is not defined

第一步应该始终是找到一个可以在没有循环或变量的情况下工作的命令。不要尝试为无法运行一次的东西编写循环!不要泛化在特定情况下无法使用的命令!

这是一个从索引0 获取config-var1 的有效命令。

$ jq -r '.["protocol-config"][0]["config-var1"]' < json
vc1

现在我们可以尝试抽象出参数,进行测试以确保它仍然有效:

$ jq -r --arg i "0" --arg var "config-var1" \
    '.["protocol-config"][$i|tonumber][$var]' < json
vc1

现在我们有了获取单个项目的有效方法,我们可以通过循环多次执行此操作:

$ 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

【讨论】:

  • 加上一个很好的解释。但它不应该输出 4 个值吗?另外您可能想知道jq 的最新版本引入了startsWith() 功能...
  • @hek2mgl 也许吧。我理解目标是为特定条目获取预定变量。可能是为了扁平化所有条目的所有“config-*”变量。
  • 是的,也许。 (可能我只是弄错了)。然而,startsWith 很好,但不是当今大多数发行版附带的 jq 的一部分。但在下一次更新后它应该可用! :P
【解决方案2】:
  1. 我不清楚最初的问题陈述,但我怀疑没有必要多次调用 jq,甚至根本不需要使用任何 bash 脚本。 (jq 速度很快,但启动时会有一些开销。)

例如,假设您想将“var”值列表传递给 jq 程序。这可以通过以下方式完成:

$ jq -n --arg x '["var2","var2"]' '$x|fromjson'
[
  "var2",
  "var2"
]
  1. 关于“startswith”——jq 当前的“稳定”版本是 1.4 版,从 2014 年 6 月开始提供;它具有过滤器 startswith/1,自 2013 年 12 月起可用。有关可用下载的更多信息,请特别参阅:

【讨论】:

    猜你喜欢
    • 2011-02-08
    • 1970-01-01
    • 1970-01-01
    • 2012-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多