简体   繁体   中英

How to get JQ name/value pair from nested (array?) response?

I am looping through a JSON response file and succeed to store Name/Value pairs per iteration. I fail though due to my inexperience to correctly adjust my filter to access a nested array, part of the response. I need some guidance setting the correct JQ filter

The purpose is to loop through the response of a WEB-API curl command. In my case issues created in SonarQube and based of the existence of a specific comment, to create a JIRA ticket or not (not part of example).

#!/usr/bin/env bash
SQIssues=$(curl --user user:pass https://sonarqube.domain.nl/api/issues/search?additionalFields=comments&statuses=OPEN&types=BUG&branch=master&componentKeys=project)
for k in $(jq '.issues | keys | .[]' <<< "$SQIssues"); do
        key=$(jq -r ".issues[$k].key" <<< "$SQIssues");
        status=$(jq -r ".issues[$k].status" <<< "$SQIssues");
        // TWO LINES BELOW NOT-OK
        comuser=$(jq -r ".issues[$k] | .comments[].login" <<< "$SQIssues");
        com=$(jq -r ".issues[$k] .comments[].markdown" <<< "$SQIssues");
        echo key="$key" and status="$status" and comment="$com" by user="$comuser";
        read -n 1 -s -r -p "Press any key to continue";
done

Reponse (KEY and STATUS are grabbed correctly):

Press any key to continuekey=AWySAdI5-U8iL73rOJWx; and status=OPEN and comment= by user=
Press any key to continuekey=AWyMy9EK-U8iL73rOI-c; and status=OPEN and comment= by user=
Press any key to continuekey=AWyMy9Er-U8iL73rOI-d; and status=OPEN and comment= by user=

I succeed to get the N/V pairs on a specific level. I fail to get the N/V pairs from the "comments" array existing on the same level as eg "key" or "status"

OK =

ISSUES
-- KEY=xx
-- STATUS=xx

NOK = (n/v under comments, one level deeper)

ISSUES
-- Comments
--- KEY=xx
--- MARKDOWN=xx

I assume "comments" is an array. I try to store eg markdown value during my loop.

Example SQ response body I am trying to work with (sample input) " $SQIssues " This is a snippit from the complete response, posted on pastebin: https://pastebin.com/MNubhfWM

{
key: "AWtQSFvOvmpNDcmJ7zeY",
rule: "javascript:S930",
severity: "CRITICAL",
component: "path/to/file.js",
project: "project-name",
line: 350,
hash: "9a8c7b5d9121757995511514602d1fd3",
textRange: {},
flows: [],
status: "OPEN",
message: "This function expects no arguments, but 1 was provided.",
effort: "10min",
debt: "10min",
author: "user@domain.nl",
tags: [],
comments: [
{
key: "AWxxXwIoRqbStspvKH2w",
login: "lmolenaar",
htmlText: "<a href="https://jira.domain.nl/browse/xxx-30093" target="_blank">https://jira.domain.nl/browse/xxx-30093</a>",
markdown: "https://jira.domain.nl/browse/xxx-30093",
updatable: true,
createdAt: "2019-08-08T15:15:47+0200"
}
],
creationDate: "2019-06-04T11:33:28+0200",
updateDate: "2019-08-08T15:15:47+0200",
type: "BUG",
organization: "default-organization",
fromHotspot: false
},

For the above input I try to store comments:login and comments:markdown

  1. Using your pastebin JSON as input, and commenting-out the line beginning with // and the line beginning with read , your script actually runs to completion.

  2. Since comments is an array, writing .comments[] as you have done is a bit risky, as .comments might not have exactly one element. It would be less risky to write .comments[0] , if that is in accordance with your requirements.

  3. Your script invokes jq five times, but it would not take much effort to modify it so that jq was only called once. For some ideas on how this could be done, see eg extract 2 values from JSON object and use as variables in loop using jq and bash

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM