jq:根据参数切片数组

jq: slicing array based on argument

我正在尝试对 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 在切片运算符 [:] 中处理变量替换的方式有关,但 none 我试图解决该问题,例如通过将变量名括在花括号 .arr[0:${eidx}] 中,已经奏效了。

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

--arg name value:

This option passes a value to the jq program as a predefined variable. If you run jq with --arg foo bar, then $foo is available in the program and has the value "bar". Note that value will be treated as a string, so --arg foo 123 will bind $foo to "123".

来自 the docs(添加了重点)

所以您似乎不能使用 --arg 来传递要在切片中使用的值。在此示例中,您可以只使用 shell 扩展:

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

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

  1. 您可以使用 tonumber 将字符串转换为数字,如:

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

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