使用 jq 从 JSON 数组中的第 n 个对象中获取特定的 key:value 对
Use jq to grab specific key:value pair from nth object in a JSON array
使用此 JSON 从 Jenkins 构建 api 通过 curl
调用
{
"_class" : "org.jenkinsci.plugins.workflow.job.WorkflowRun",
"actions" : [
{
"_class" : "hudson.model.CauseAction",
"causes" : [
{
"_class" : "jenkins.branch.BranchIndexingCause",
"shortDescription" : "Branch indexing"
}
]
},
{
"_class" : "hudson.model.ParametersAction",
"parameters" : [ "..." ]
},
{
"_class" : "hudson.tasks.junit.TestResultAction",
"failCount" : 1,
"skipCount" : 14,
"totalCount" : 222,
"urlName" : "testReport"
}
],
"artifacts" : [ "..." ],
"result" : "UNSTABLE",
"previousBuild" : {
"number" : 98,
"url" : "<some Url>"
}
}
为什么我可以做jq '{result}' <fileNameWithJSON>
并得到
{ "result" : "UNSTABLE" }
但我不能做 jq '{.actions[2] failCount}' <fileNameWithJSON>
或其他变体,例如
jq '{actions[2].failCount}'
jq '{actions[2] failCount}'
jq '{actions .[2].failCount}'
等等
得到{ "failCount" : "1" }
?
我想抓取 result
,以及 actions[2] failCount
、actions[2] skipCount
和 actions[2] totalCount
来创建一个新的 JSON,如下所示:
{ "result" : "UNSTABLE","failCount" : 1, "skipCount" : 14,"totalCount" : 222}
编辑:
我的目标是不必重新指定密钥,以防它们在 api 中发生更改。我基本上不想要这个:
{result, "failCount":.actions[2].failCount, "skipCount":.actions[2].skipCount, "totalCount": .actions[2].totalCount}
jq 只能在对象字面量中将一个对象的直接字段复制到另一个对象。尽管在支持这种功能的其他语言中肯定有可能,但它并没有被编程为比这更深入。
如果您的目标是尽量减少 属性 名称的重复,您只需稍微重写一下过滤器即可。
{result} + (.actions[2] | {failCount,skipCount,totalCount})
{}
语法是糖。当您需要一个简单的表达式时,它旨在用作快捷方式,但当您真正想要的更有趣时,没有理由使用相同的缩短语法。
jq '
.actions[2] as $a2 | # assign second action to a variable
{ "result": .result, # refer direct to original input when appropriate...
"skipCount": $a2.skipCount, # ...or to that variable otherwise.
"failCount": $a2.failCount,
"totalCount": $a2.totalCount}
' <<<"$json"
My goal was to not have to re-specify the keys in case they changed in the api.
如果这是主要目标之一,您可能需要考虑以下示例的方法,该方法也不假设 .actions
的哪个元素包含感兴趣的信息:
{ result } + (.actions[] | select(has("failCount")))
使用您的示例数据,这将产生:
{
"result": "UNSTABLE",
"_class": "hudson.tasks.junit.TestResultAction",
"failCount": 1,
"skipCount": 14,
"totalCount": 222,
"urlName": "testReport"
}
如果您不需要一些额外的字段,您可以删除它们,例如如果您绝对不想要“_class”,您可以将 del(._class)
添加到管道中。
使用此 JSON 从 Jenkins 构建 api 通过 curl
调用{
"_class" : "org.jenkinsci.plugins.workflow.job.WorkflowRun",
"actions" : [
{
"_class" : "hudson.model.CauseAction",
"causes" : [
{
"_class" : "jenkins.branch.BranchIndexingCause",
"shortDescription" : "Branch indexing"
}
]
},
{
"_class" : "hudson.model.ParametersAction",
"parameters" : [ "..." ]
},
{
"_class" : "hudson.tasks.junit.TestResultAction",
"failCount" : 1,
"skipCount" : 14,
"totalCount" : 222,
"urlName" : "testReport"
}
],
"artifacts" : [ "..." ],
"result" : "UNSTABLE",
"previousBuild" : {
"number" : 98,
"url" : "<some Url>"
}
}
为什么我可以做jq '{result}' <fileNameWithJSON>
并得到
{ "result" : "UNSTABLE" }
但我不能做 jq '{.actions[2] failCount}' <fileNameWithJSON>
或其他变体,例如
jq '{actions[2].failCount}'
jq '{actions[2] failCount}'
jq '{actions .[2].failCount}'
等等
得到
{ "failCount" : "1" }
?
我想抓取 result
,以及 actions[2] failCount
、actions[2] skipCount
和 actions[2] totalCount
来创建一个新的 JSON,如下所示:
{ "result" : "UNSTABLE","failCount" : 1, "skipCount" : 14,"totalCount" : 222}
编辑:
我的目标是不必重新指定密钥,以防它们在 api 中发生更改。我基本上不想要这个:
{result, "failCount":.actions[2].failCount, "skipCount":.actions[2].skipCount, "totalCount": .actions[2].totalCount}
jq 只能在对象字面量中将一个对象的直接字段复制到另一个对象。尽管在支持这种功能的其他语言中肯定有可能,但它并没有被编程为比这更深入。
如果您的目标是尽量减少 属性 名称的重复,您只需稍微重写一下过滤器即可。
{result} + (.actions[2] | {failCount,skipCount,totalCount})
{}
语法是糖。当您需要一个简单的表达式时,它旨在用作快捷方式,但当您真正想要的更有趣时,没有理由使用相同的缩短语法。
jq '
.actions[2] as $a2 | # assign second action to a variable
{ "result": .result, # refer direct to original input when appropriate...
"skipCount": $a2.skipCount, # ...or to that variable otherwise.
"failCount": $a2.failCount,
"totalCount": $a2.totalCount}
' <<<"$json"
My goal was to not have to re-specify the keys in case they changed in the api.
如果这是主要目标之一,您可能需要考虑以下示例的方法,该方法也不假设 .actions
的哪个元素包含感兴趣的信息:
{ result } + (.actions[] | select(has("failCount")))
使用您的示例数据,这将产生:
{
"result": "UNSTABLE",
"_class": "hudson.tasks.junit.TestResultAction",
"failCount": 1,
"skipCount": 14,
"totalCount": 222,
"urlName": "testReport"
}
如果您不需要一些额外的字段,您可以删除它们,例如如果您绝对不想要“_class”,您可以将 del(._class)
添加到管道中。