Request
curl -XGET http\://my_host\:9111/api/issues/search\?componentKeys\=my_poject\&facets\=severities\&p\=1\&ps\=1
Here response:
{
"total": 10057,
"p": 1,
"ps": 1,
"paging": {
"pageIndex": 1,
"pageSize": 1,
"total": 10057
},
"effortTotal": 51031,
"issues": [
{
"key": "AX0NVCNfENszTAxEgX5e",
"rule": "java:S122",
"severity": "MINOR",
"component": "my_project:SomeFile.java",
"project": "my_project",
"line": 241,
"hash": "1111111111",
"textRange": {
"startLine": 241,
"endLine": 241,
"startOffset": 0,
"endOffset": 46
},
"flows": [],
"status": "OPEN",
"message": "At most one statement is allowed per line, but 2 statements were found on this line.",
"effort": "1min",
"debt": "1min",
"author": "eugeniur",
"tags": [
"convention"
],
"creationDate": "2021-11-11T06:40:05 0200",
"updateDate": "2021-11-11T06:40:05 0200",
"type": "CODE_SMELL",
"scope": "MAIN"
}
],
"components": [
{
"key": "my_project",
"enabled": true,
"qualifier": "TRK",
"name": "Parent",
"longName": "Parent"
},
{
"key": "my_project:MyFile.java",
"enabled": true,
"qualifier": "FIL",
"name": "XStartDServerComponent.java",
"longName": "MyFile.java",
"path": "MyFile.java"
}
],
"facets": [
{
"property": "severities",
"values": [
{
"val": "CRITICAL",
"count": 5818
},
{
"val": "MAJOR",
"count": 1459
},
{
"val": "BLOCKER",
"count": 1286
},
{
"val": "MINOR",
"count": 1163
},
{
"val": "INFO",
"count": 331
}
]
}
]
}
Now I want to extract keys: "total", "issues", "facets.values"
.
So I try this in my bash script:
#!/bin/bash
readonly BASE_URL=http://my_host:9111/api
readonly PROJECT_KEY=my_project
read totalIssues facetsArr issuesArr < <(echo $(curl -XGET $BASE_URL/issues/search\?componentKeys\=$PROJECT_KEY\&facets\=severities\&p\=1\&ps\=1 |
jq -r '.total, .issues[], .facets[].values'))
echo "total : $totalIssues"
echo "facetsArr : $facetsArr"
echo "issuesArr : $issuesArr"
But result is:
total : 10057
facetsArr : {
issuesArr : "key": "AX0NVCNfENszTAxEgX5e", "rule": "java:S122", "severity": "MINOR", "component": "MyFile.java", "project": "myProject", "line": 241, "hash": "b68d3b4b390c81e2714d263b31acdd08", "textRange": { "startLine": 241, "endLine": 241, "startOffset": 0, "endOffset": 46 }, "flows": [], "status": "OPEN", "message": "At most one statement is allowed per line, but 2 statements were found on this line.", "effort": "1min", "debt": "1min", "author": "eugeniur", "tags": [ "convention" ], "creationDate": "2021-11-11T06:40:05 0200", "updateDate": "2021-11-11T06:40:05 0200", "type": "CODE_SMELL", "scope": "MAIN" } [ { "val": "CRITICAL", "count": 5818 }, { "val": "MAJOR", "count": 1459 }, { "val": "BLOCKER", "count": 1286 }, { "val": "MINOR", "count": 1163 }, { "val": "INFO", "count": 331 } ]
Why "facetsArr" get incorrect value?
The "facetsArr" must be:
facetsArr : [ { "val": "CRITICAL", "count": 5818 }, { "val": "MAJOR", "count": 1459 }, { "val": "BLOCKER", "count": 1286 }, { "val": "MINOR", "count": 1163 }, { "val": "INFO", "count": 331 } ]
CodePudding user response:
- Use string manipulation to insert a newline (
\n
) between each value, each line will now contain the value you're trying to catch - Quote the
jq
command since it may contain spaces [info] - Set
IFS
to a newline [info] - Use
read -d ''
[docs]-d delim
continue until the first character of DELIM is read, rather than newline
Applying those fixes, the script will look like:
IFS=$'\n'
read -r -d '' totalIssues facetsArr issuesArr <<< "$( jq -r '"\(.total)\n\(.facets[].values)\n\(.issues[])"' input)"
echo "total : $totalIssues"
echo "facetsArr : $facetsArr"
echo "issuesArr : $issuesArr"
Note: I've replaced the curl command with an actual file called input
containing OP's JSON
The output will be:
total : 10057
facetsArr : [{"val":"CRITICAL","count":5818},{"val":"MAJOR","count":1459},{"val":"BLOCKER","count":1286},{"val":"MINOR","count":1163},{"val":"INFO","count":331}]
issuesArr : {"key":"AX0NVCNfENszTAxEgX5e","rule":"java:S122","severity":"MINOR","component":"my_project:SomeFile.java","project":"my_project","line":241,"hash":"1111111111","textRange":{"startLine":241,"endLine":241,"startOffset":0,"endOffset":46},"flows":[],"status":"OPEN","message":"At most one statement is allowed per line, but 2 statements were found on this line.","effort":"1min","debt":"1min","author":"eugeniur","tags":["convention"],"creationDate":"2021-11-11T06:40:05 0200","updateDate":"2021-11-11T06:40:05 0200","type":"CODE_SMELL","scope":"MAIN"}
CodePudding user response:
Slightly inefficient, but it would be much simpler to just parse the (small) response 3 times.
#!/bin/bash
readonly BASE_URL=http://my_host:9111/api
readonly PROJECT_KEY=my_project
response=$(curl -XGET "$BASE_URL/issues/search?componentKeys=$PROJECT_KEY&facets=severities&p=1&ps=1")
total=$(jq '.total' <<< "$response")
issues=$(jq '.issues' <<< "$response")
facets=$(jq '.facets[].values' <<< "$response")
# ...
Then you don't have to worry about constructing a single output with jq
that bash
must parse anyway.
(I've intentionally left the value of issues
a JSON array, rather than a stream of issues
, in the event that there is more than a single object in the array.)