用jq --arg传递的数值参数不匹配==的数据 [英] Numeric argument passed with jq --arg not matching data with ==

查看:140
本文介绍了用jq --arg传递的数值参数不匹配==的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的curl的示例JSON响应:

Here is a sample JSON response from my curl:

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

我想检查ID = 2的状态.这是我尝试的命令:

I want to check the status of ID=2. Here is the command I tried:

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

响应:没有响应

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

I tried value 2 without quotes and still no result.

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

By contrast, if I try the command with a literal 2, it works:

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

响应:

"Successful"

我被困住了.谁能帮我找出问题所在?

I'm stuck. Can anyone help me identify the problem?

推荐答案

jq具有数据类型意识:

jq is data-type-aware:

    JSON 输入中定义的
  • .ID数字

,但是随--arg一起传递的任何命令行参数(例如此处的v)始终是 string (无论您引用的值还是

but any command-line argument passed with --arg (such as v here) is invariably a string (whether you quote the value or not),

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

so, in order to compare them, you must use an explicit type conversion, such as with tonumber/1:

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


鉴于您仅在此处传递 scalar 参数,使用--argjson(jq v1.5 +)的以下解决方案有点过头了,但这是一个替代显式类型转换,因为有效地传递 JSON 参数将传递 typed 数据:


Given that you're only passing a scalar argument here, the following solution, using --argjson (jq v1.5+) is a bit of an overkill, but it is an alternative to explicit type conversion in that passing a JSON argument in effect passes typed data:

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


峰值的答案表明甚至--argjson v 2都有效(在这种情况下,与$v直接起作用),这当然是最简洁的解决方案,但可能需要解释:


peak's answer demonstrates that even --argjson v 2 works (in which case comparing to $v works directly), which is certainly the most concise solution, but may require an explanation:

  • 即使2可能不会像JSON那样看起来" ,它仍然是:这是有效的JSON文本,其中包含单个 value 类型为 number的数字(请参见 json.org ).

  • Even though 2 may not look like JSON, it is: it is a valid JSON text containing a single value of type number (see json.org).

  • 具体来说,这是2是一个不带引号的令牌的事实,该令牌以 digit 开头,在 JSON (相当于JSON的 string 值为"2",必须从外壳中将其作为'"2"'传递-注意嵌入式双引号).
  • Specifically, it is the fact that 2 is an unquoted token that starts with a digit that makes it a number in the context of JSON (the JSON string-value equivalent is "2", which from the shell would have to be passed as '"2"' - note the embedded double quotes).

因此,jq--argjson -v 2解释为数字,并且比较.ID == $v可以按预期工作(请注意,--argjson -v '2'/--argjson -v "2"相同) shell会在jq看到值之前删除引号.)
相比之下,您使用--arg传递的任何内容始终都是原样使用的 string 值.

Therefore jq interprets --argjson -v 2 as a number, and comparison .ID == $v works as intended (note that the same applies to --argjson -v '2' / --argjson -v "2", where the shell removes the quotes before jq sees the value).
By contrast, anything you pass with --arg is always a string value that is used as-is.

换句话说:--argjson的目的是接受任意JSON文本作为字符串(例如上例中的'{ "ID": 2 }'),也可以用于传递数字字符串标量强制将其解释为数字.
布尔字符串truefalse也可以使用相同的技术.

In other words: --argjson, whose purpose is to accept arbitrary JSON texts as strings (such as '{ "ID": 2 }' in the example above), can also be used to pass number-string scalars to force their interpretation as numbers.
The same technique also works with Boolean strings true and false.

帽子提示峰值以寻求帮助.

Tip of the hat to peak for his help.

这篇关于用jq --arg传递的数值参数不匹配==的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆