json - 使用 jq --arg 传递的数字参数与 == 不匹配的数据

标签 json bash parameter-passing jq

这是来 self 的 curl 的示例 JSON 响应:

{
  "success": true,
  "message": "jobStatus",
  "jobStatus": [
    {
      "ID": 9,
      "status": "Successful"
    },
    {
      "ID": 2,
      "status": "Successful"
    },
   {
      "ID": 99,
      "status": "Failed"
    }
  ]
}

我想查看 ID=2 的状态。这是我试过的命令:

cat test.txt|jq --arg v "2" '.jobStatus[]|select(.ID == $v)|.status'

回复:没有

我尝试了不带引号的 2 值,但仍然没有结果。

相比之下,如果我尝试使用 literal 2 命令,它会起作用:

cat test.txt | jq '.jobStatus[]|select(.ID == 2)|.status'

回复:

"Successful"

我卡住了。谁能帮我找出问题所在?

最佳答案

jq 是数据类型感知的:

  • .ID,在 JSON 输入中定义,是一个数字

  • 但是任何通过 --arg 传递的命令行参数(比如这里的 v)总是 string(无论你是否引用该值),

因此,为了比较它们,您必须使用显式类型转换,例如 tonumber/1 :

jq --arg v '2' '.jobStatus[] | select(.ID == ($v | tonumber)) | .status' test.txt

鉴于您只在此处传递一个标量参数,以下解决方案使用--argjson (jq v1.5+ ) 有点矫枉过正,但它是显式类型转换的替代方案,因为传递 JSON 参数实际上传递了typed 数据:

jq --argjson v '{ "ID": 2 }' '.jobStatus[] | select(.ID == $v.ID) | .status' test.txt

peak's answer证明甚至 --argjson v 2 有效(在这种情况下与 $v 直接比较有效),这肯定是简洁解决方案,但可能需要解释:

  • 尽管 2 可能看起来不像 JSON,但它是:它是一个有效的 JSON 文本,包含一个输入数字(参见json.org)。

    • 具体来说,2 是一个以数字 开头的未加引号 标记,这使它成为JSON(等效于 JSON string 的值是 "2",它必须从 shell 传递为 '"2 "' - 注意嵌入的双引号)。
  • 因此jq--argjson -v 2解释为一个数字,并比较.ID == $ v 按预期工作(请注意,这同样适用于 --argjson -v '2'/--argjson -v "2",其中 shell在 jq 看到值之前删除引号)。
    相比之下,您使用 --arg 传递的任何内容始终是按原样使用的字符串值。

  • 换句话说:--argjson,其目的是接受任意JSON文本作为字符串(例如'{ "ID": 2 }'在上面的示例中)也可以用于传递数字字符串标量以强制将它们解释为数字。
    同样的技术也适用于 bool 字符串 truefalse


帽子的提示 peak感谢他的帮助。

关于json - 使用 jq --arg 传递的数字参数与 == 不匹配的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41772776/

相关文章:

c++ - 将一个函数作为参数传递给另一个函数的不同方法有什么区别?

json - python 从 json 中提取特定的键和值不起作用

javascript - 在 Javascript 中获取对象的任何级别的元素

linux - 为什么 bash 不调用 python 脚本?

linux - Bash:如何使用两个单独的 echo 命令回显 "hey"和 ", how are you?"?

java - 为什么我无法重新分配传递给静态方法的 LinkedList 引用?

c++ - 传递数组 : by reference to the first element 的病态方式

php - 如何构建 mySQL 函数来访问 K2 extra_fields

php - 将值从 PHP 传递到 Javascript 的权威方法

带有 --index-filter : strange bash error ( ! 的 git-filter-branch:找不到事件)