use*_*929 5 bash json parameter-passing jq
以下是我的curl的示例JSON响应:
{
"success": true,
"message": "jobStatus",
"jobStatus": [
{
"ID": 9,
"status": "Successful"
},
{
"ID": 2,
"status": "Successful"
},
{
"ID": 99,
"status": "Failed"
}
]
}
Run Code Online (Sandbox Code Playgroud)
我想检查ID = 2的状态.这是我试过的命令:
cat test.txt|jq --arg v "2" '.jobStatus[]|select(.ID == $v)|.status'
Run Code Online (Sandbox Code Playgroud)
回复:没有
我试着2没有引号的价值但仍然没有结果.
相比之下,如果我尝试使用文字 的命令2,它的工作原理:
cat test.txt | jq '.jobStatus[]|select(.ID == 2)|.status'
Run Code Online (Sandbox Code Playgroud)
响应:
"Successful"
Run Code Online (Sandbox Code Playgroud)
我被卡住了.任何人都可以帮我识别问题吗?
jq是数据类型感知:
.ID,如JSON输入中定义的,是一个数字,
但是传递的任何命令行参数--arg(例如vhere)总是一个字符串(无论你是否引用值),
因此,为了比较它们,您必须使用显式类型转换,例如tonumber/1:
jq --arg v '2' '.jobStatus[] | select(.ID == ($v | tonumber)) | .status' test.txt
Run Code Online (Sandbox Code Playgroud)
鉴于你只是在这里传递一个标量参数,下面的解决方案,使用--argjson(jqv1.5 +)有点过分,但它是显式类型转换的替代方法,因为传递JSON参数实际上传递了类型化数据:
jq --argjson v '{ "ID": 2 }' '.jobStatus[] | select(.ID == $v.ID) | .status' test.txt
Run Code Online (Sandbox Code Playgroud)
peak的答案表明即使--argjson v 2有效(在这种情况下$v直接与作品比较),这当然是最简洁的解决方案,但可能需要解释:
尽管2可能看起来不像JSON,但它是:它是一个有效的JSON文本,包含一个类型为number的值(参见json.org).
2是一个不带引号的标记,以一个数字开头,使得它成为JSON上下文中的数字(JSON 字符串 -值等价"2",来自shell必须传递'"2"'- 注意嵌入的双引号).因此,jq解释--argjson -v 2为数字,并且比较.ID == $v按预期工作(请注意,这同样适用于--argjson -v '2'/ --argjson -v "2",其中shell在jq看到值之前删除引号).
相比之下,您传递的任何内容--arg始终是按原样使用的字符串值.
换句话说:--argjson,其目的是接受任意JSON文本作为字符串(例如'{ "ID": 2 }'在上面的示例中),也可以用于传递数字字符串标量以强制将它们解释为数字.
相同的技术也适用于布尔字符串true和false.
帽子的尖端为他的帮助达到顶峰.
假设您想要检查 JSON 值2,您可以选择 - 将 --arg 的参数转换为数字,或将 --argjson 与数字参数一起使用。这些替代方案如下所示:
jq --arg v 2 '.jobStatus[] | select(.ID == ($v|tonumber) | .status'
jq --argjson v 2 '.jobStatus[] | select(.ID == $v) | .status'
Run Code Online (Sandbox Code Playgroud)
请注意,--argjson 需要相对较新版本的 jq。
当然,如果您想“规范化”.ID,以便它始终被视为字符串,您可以编写:
jq --arg v 2 '.jobStatus[] | select((.ID|tostring) == $v) | .status'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1331 次 |
| 最近记录: |