usert4jju7
usert4jju7

Reputation: 1813

Parse json using jq utility & append fields together

One of the many thousand json blocks in an array of json blocks looks as follows -

{
  "id": 4409976,
  "name": "MKLIU",
  "version": "1.0",
  "package_type": "generic",
  "status": "default",
  "_links": {
    "web_path": "/part1/part2/ONEMTH/part4/-/part5/part6",
    "delete_api_path": "https://example.com/api/v1/part40/part90/part65/part73"
  },
  "created_at": "2019-01-02T10:52:34.857Z",
  "project_id": 667845,
  "project_path": "hereitis/downloads/ONEMTH/MKLIU",
  "tags": []
}

I am looking to parse the array of json blocks on Ubuntu command line using jq utility

Expected output

667845#MKLIU#ONEMTH

The code I've written so far is as below

curl <some url> | jq -r '.[] | [.project_id, .name, ._links.web_path] | join("#")'

I can't work out how to pull out just the part ONEMTH from ._links.web_path

Could use project_path field too from the json block to parse out the value.

Please could I request some guidance ?

Upvotes: 2

Views: 290

Answers (4)

Shankar
Shankar

Reputation: 126

You can use the following to get the desired output.

echo $(curl <some-url> | jq -r '.[] | [.project_id, .name] | join("#")' && curl <some-url> | jq -r '.[] |  ._links.web_path' | awk -F/ '{ print $4}') | tr ' ' '#'

PS: There may be a more optimal way to achieve this. Comments are welcome!

Upvotes: 1

Inian
Inian

Reputation: 85845

The key is to use the split/1 method on a delimiter(/) and extract the field required by specifying the index

[ .project_id, .name, (._links.web_path | split("/")[3]) ] | join("#")

jqplay - working demo

Upvotes: 2

bnaecker
bnaecker

Reputation: 6440

One can accomplish this with:

$ jq '{ project_id, name, "path": ._links.web_path | split("/") | .[3] } | join ("#")' < example.txt
"667845#MKLIU#ONEMTH"

The project_id and name fields are "passed through" from the input. You didn't specify the exact rules for pulling out your target substring, "ONEMTH", from the _links.web_path key. The above assumes it's always the fourth element resulting from splitting the string on "/". Please update your question if that's not always the case.

The data is then collected into an object, rather than array, and the values joined by the "#" character.

Interestingly, using an array here doesn't seem to work:

$ jq '[.project_id, .name, ._links.web_path | split("/") | .[3]] | join ("#")' < example.txt
jq: error (at <stdin>:14): split input and separator must be strings

I'm not sure why. The jq documentation explicitly states that array elements may be pipelines, so it seems like that should be fine. But in any case, the former works!

Upvotes: 1

Benjamin W.
Benjamin W.

Reputation: 52451

For just the one object you show, which corresponds to your code after .[]: you can use string interpolation and split / array indexing to extract the web path string:

jq -r '"\(.project_id)#\(.name)#\(._links.web_path | split("/")[3])"'

Upvotes: 2

Related Questions