Home > Net >  Extract values from an array in json in one line in Linux bash with jq
Extract values from an array in json in one line in Linux bash with jq

Time:01-27

I am extending here my recent question about jq since my requirements changed and I am still confused with map function.

Given such a service-def-test.json (very simplified from my real use case):

{
    "definition": {
        "services": [{
                "image": {
                    "name": "img1",
                    "tag": "2.0.1"
                }
            }, {
                "image": {
                    "name": "img2",
                    "tag": "1.4.0"
                }
            }, {
                "image": {
                    "name": "img3",
                    "tag": "1.2.5"
                }
            }
        ]
    }
}

I now would like to get a one-line list of values:

[img1:2.0.1, img2:1.4.0, img3:1.2.
to store eventually in a COMPONENT_IMAGES variable.

From the previous answer,

jq -r '.definition.services | " "COMPONENT_IMAGES=\"\(map(.image.name, .image.tag) | join(", "))\"" ' service-def-test.json

generates

COMPONENT_IMAGES="img1, 2.0.1, img2, 1.4.0, img3, 1.2.5"

but this I want only 3 items in my output array.

I am looking to get

COMPONENT_IMAGES="img1:2.0.1, img2:1.4.0, img3:1.2.5"

What am I missing here? Thanks!

CodePudding user response:

map lets you filter each array item individually. Here, we descend to .image, and concatenate the value of .name, a literal colon ":", and the value of .tag. The mapped array can then be joined with a glue string ", ".

jq -r '
  .definition.services
  | "COMPONENT_IMAGES=\""   (map(.image | .name   ":"   .tag) | join(", "))   "\""
'
COMPONENT_IMAGES="img1:2.0.1, img2:1.4.0, img3:1.2.5"

Demo


If you prefer using string interpolation, here's its equivalent:

jq -r '
  .definition.services
  | "COMPONENT_IMAGES=\"\(map(.image | "\(.name):\(.tag)") | join(", "))\""
' 
COMPONENT_IMAGES="img1:2.0.1, img2:1.4.0, img3:1.2.5"

Demo

  • Related