jmog jmog - 1 month ago 8
Bash Question

Use jq to grab specific key:value pair from nth object in a JSON array

Using this JSON taken from a Jenkins build api call via 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>"
}
}


Why can I do
jq '{result}' <fileNameWithJSON>
and get

{ "result" : "UNSTABLE" }


But I cannot do
jq '{.actions[2] failCount}' <fileNameWithJSON>
or other variations such as


  • jq '{actions[2].failCount}'

  • jq '{actions[2] failCount}'

  • jq '{actions .[2].failCount}'

  • etc.

    to get
    { "failCount" : "1" }
    ?



I want to grab the
result
, as well as
actions[2] failCount
,
actions[2] skipCount
and
actions[2] totalCount
to create a new JSON like this:

{ "result" : "UNSTABLE","failCount" : 1, "skipCount" : 14,"totalCount" : 222}


EDIT:

My goal was to not have to re-specify the keys in case they changed in the api. I essentially didn't want this:

{result, "failCount":.actions[2].failCount, "skipCount":.actions[2].skipCount, "totalCount": .actions[2].totalCount}

Answer Source

jq can only copy direct fields from one object to another in object literals. It wasn't programmed to go any deeper than that though it is most certainly possible in other languages that support this kind of feature.

If your goal is to minimize the repetition of the property names, you will just have to rewrite the filter a bit.

{result} + (.actions[2] | {failCount,skipCount,totalCount})