【问题标题】:jq: slicing array based on argumentjq:根据参数切片数组
【发布时间】:2017-12-13 05:15:00
【问题描述】:

我正在尝试在 jq 中对数组进行切片,其中结束索引作为参数从 shell (bash) 传递:

end_index=7
cat obj.json | jq --arg eidx $end_index, '.arr[0:$eidx]'

当索引被硬编码时,这可以正常工作

cat obj.json | jq '.arr[0:7]'

但在顶部的示例中,我收到一条错误消息

jq: error (at <stdin>:0): Start and end indices of an array slice must be numbers

我怀疑这可能与 jq 如何处理切片运算符 [:] 中的变量替换有关,但我没有尝试解决问题,例如通过将变量名括在花括号 .arr[0:${eidx}] 中,已经奏效了。

【问题讨论】:

    标签: json bash casting command-line-arguments jq


    【解决方案1】:

    当您通过--arg 传递参数时,它被视为字符串,而不是int:

    --arg 名称值:

    此选项将值作为预定义变量传递给 jq 程序。如果您使用 --arg foo bar 运行 jq,则 $foo 在程序中可用并且具有值“bar”。 注意 value 将被视为字符串,因此 --arg foo 123 会将 $foo 绑定到“123”

    来自the docs(已添加重点)

    所以看起来您不能使用--arg 来传递要在切片中使用的值。在这个例子中,你可以只使用 shell 扩展:

    jq ".arr[0:$end_index]" obj.json
    

    双引号将在将变量传递给jq 之前让shell 扩展您的变量(尽管会发生其他扩展,因此请确保您的意思是它们会发生。

    【讨论】:

    • 感谢您指出解释为字符串。 Shell 扩展并不总是适用于更复杂的 jq 命令,这就是我首先使用 --arg 的原因
    【解决方案2】:
    1. 您可以使用tonumber 将字符串转换为数字,如下所示:

    jq --arg eidx 1 '.arr[0:($eidx|tonumber)]'
    
    1. 如果您的 jq 足够新,您可以使用 --argjson 而不是 --arg

    jq --argjson eidx 1 '.arr[0:$eidx]'
    

    【讨论】:

    • --argjson 为我完成了这项工作
    猜你喜欢
    • 2015-05-12
    • 2012-11-10
    • 2015-01-25
    • 1970-01-01
    • 2015-04-15
    • 1970-01-01
    • 1970-01-01
    • 2020-12-26
    • 1970-01-01
    相关资源
    最近更新 更多