以下是我的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
。
相比之下,如果我使用文字 2
尝试命令,它可以工作:
cat test.txt | jq '.jobStatus[]|select(.ID == 2)|.status'
响应:
"Successful"
我被困住了。任何人都可以帮我确定问题吗?
答案 0 :(得分:8)
jq
是数据类型感知:
.ID
,在 JSON 输入中定义,是号,
但是通过--arg
传递的任何命令行参数(例如此处v
)总是一个字符串(无论你是否是否引用该值,
因此,为了比较它们,您必须使用显式类型转换,例如使用tonumber/1
:
jq --arg v '2' '.jobStatus[] | select(.ID == ($v | tonumber)) | .status' test.txt
鉴于您只在此处传递标量参数,使用--argjson
(jq
v1.5 +)的以下解决方案有点过分,但它是替代显式类型转换,因为传递 JSON 参数实际上传递类型数据:< / p>
jq --argjson v '{ "ID": 2 }' '.jobStatus[] | select(.ID == $v.ID) | .status' test.txt
peak's answer表明偶--argjson v 2
有效(在这种情况下与$v
比较直接工作),这肯定是最简明 解决方案,但可能需要解释:
即使2
可能看起来像,但它是:它是一个有效的JSON文本,包含的单个值 >数字(见json.org)。
2
是未加引号的标记,以数字开头,使其成为上下文中的数字JSON (JSON 字符串 - 值等效于"2"
,来自shell的必须以'"2"'
传递 - 请注意嵌入的双引号。 / LI>
因此jq
将--argjson -v 2
解释为数字,并且比较.ID == $v
按预期工作(请注意,这同样适用于{{1} } / --argjson -v '2'
,其中shell在--argjson -v "2"
看到值之前删除了引号
相比之下,您使用jq
传递的任何内容始终是按原样使用的字符串值。
换句话说:--arg
,其目的是接受任意JSON文本作为字符串(例如上例中的--argjson
),也可用于传递数字字符串< em> scalars 强制将其解释为数字
相同的技术也适用于布尔字符串'{ "ID": 2 }'
和true
。
向peak寻求帮助的提示。
答案 1 :(得分:3)
假设您要检查JSON值2
,您可以选择 - 将--arg的参数转换为数字,或者使用带有数字参数的--argjson。以下说明了这些替代方案:
jq --arg v 2 '.jobStatus[] | select(.ID == ($v|tonumber) | .status'
jq --argjson v 2 '.jobStatus[] | select(.ID == $v) | .status'
请注意--argjson需要相对较新版本的jq。
当然,如果你想&#34;正常化&#34; .ID这样它总是被视为字符串,你可以写:
jq --arg v 2 '.jobStatus[] | select((.ID|tostring) == $v) | .status'