【问题标题】:JQ error: is not defined at <top-level> when trying to add values to jq templateJQ 错误:尝试向 jq 模板添加值时未在 <top-level> 定义
【发布时间】:2025-12-16 04:25:02
【问题描述】:

我有一个 .jq 模板,我想更新示例列表下的值,格式为:

{
  "test": "abc",
  "p": "1",
  "v": "1.0.0",
  "samples": [
    {
      "uptime": $uptime,
      "curr_connections": $curr_connections,
      "listen_disabled_num": $listen_disabled_num,
      "conn_yields": $conn_yields,
      "cmd_get": $cmd_get,
      "cmd_set": $cmd_set,
      "bytes_read": $bytes_read,
      "bytes_written": $bytes_writtem,
      "get_hits": $get_hits,
      "rejected_connections": $rejected_connections,
      "limit_maxbytes": $limit_maxbytes,
      "cmd_flush": $cmd_flush
    }
  ]
}

我的 shell 脚本如下,我基本上是在运行一个命令来提取一些 memcached 输出统计信息,并希望将一些结果作为键/值插入到 jq 模板中。

JQ=`cat template.jq`

SAMPLES=(uptime curr_connections listen_disabled_num conn_yields cmd_get cmd_set cmd_flush bytes_read bytes_written get_hits rejected_connections limit_maxbytes)

for metric in ${SAMPLES[*]}
do
  KEY=$(echo stats | nc $HOST $PORT | grep $metric | awk '{print $2}')
  VALUE=$(echo stats | nc $HOST $PORT | grep $metric | awk '{print $3}')

  echo "Using KEY: $KEY with value: $VALUE"

  jq -n --argjson $KEY $VALUE -f template.jq
done

不确定这是否是处理这种情况的最佳方法,但我收到了大量错误,例如:

jq: error: conn_yields/0 is not defined at <top-level>, line 12:
      "conn_yields": $conn_yields,
jq: error: cmd_get/0 is not defined at <top-level>, line 13:
      "cmd_get": $cmd_get,
jq: error: cmd_set/0 is not defined at <top-level>, line 14:
      "cmd_set": $cmd_set,

【问题讨论】:

    标签: json templates jq


    【解决方案1】:

    如果您要使用-f template.jq 调用jq,则必须在命令行中单独 逐一设置template.jq 中的每个$ 变量。在你的情况下,这看起来不是一个非常愉快的选择。

    如果你被 template.jq 卡住了,那么这将是一个艰难的过程,尽管除了在命令行上设置 $-variables 之外还有其他选择。

    请参阅 jq Cookbook 中的 https://github.com/stedolan/jq/wiki/Cookbook#using-jq-as-a-template-engine 以了解使用 $-variables 的替代方法。例如,考虑一下这个“解构”说明的含义:

    jq -nc '{a:1,b:2} as {a: $a, b:$b} | [$a,$b]'
    [1,2]  
    

    另一种选择

    在您的特定情况下,您可以将 template.jq 中的所有“$”字符替换为“.”,然后使用适当的键传入 JSON 对象;例如将$uptime 更改为.uptime,然后包含uptime 的键/值对。

    【讨论】:

    • 感谢您的反馈!当您说“在命令行设置”时,您的意思是将它们设置为环境变量吗? @峰
    • 没有。 jq $-variables 与 shell 或环境变量之间没有关系。有关详细信息,请参阅 Cookbook 和/或 jq 手册。