How do I print a specific value of an array given a condition in jq if there is no key specified

9/20/2021

I am trying to output the value for .metadata.name followed by the student's name in .spec.template.spec.containers[].students[] array using the regex test() function in jq.

I am having trouble to retrieve the individual array value since there is no key specified for the students[] array.

For example, if I check the students[] array if it contains the word "Jeff", I would like the output to display as below:

student-deployment:    Jefferson

What i have tried:

I've tried the command below which somewhat works but I am not sure how to get only the "Jefferson" value. The command below would print out all of the students[] array values which is not what I want. I am using Powershell to run the command below.

kubectl get deployments -o json | jq -r '.items[] | select(.spec.template.spec.containers[].students[]?|test("\"^Jeff.\"")) | .metadata.name, "\":\t\"", .spec.template.spec.containers[].students'

Is there a way to print a specific value of an array given a condition in jq if there is no key specified? Also, would the solution work if there are multiple deployments?

The deployment template below is in json and I shortened it to only the relevant parts.

{
    "apiVersion": "v1",
    "items": [
        {
            "apiVersion": "apps/v1",
            "kind": "Deployment",
            "metadata": {
                "name": "student-deployment",
                "namespace": "default"
            },
            "spec": {
                "template": {
                    "spec": {
                        "containers": [
                            {
                                "students": [
                                        "Alice",
                                        "Bob",
                                        "Peter",
                                        "Sally",
                                        "Jefferson"
                                ]
                            }
                        ]
                    }
                }
            }
        }
    ]
}
-- calmmash
jq
json
kubernetes
select

2 Answers

9/20/2021

For this approch, we introduce a variable $pattern. You may set it with --arg pattern to your regex, e.g. "Jeff" or "^Al" or "e

quot; to have the student list filtered by test, or leave it empty to see all students.

Now, we iterate over all .item[] elements (i.e. over "all deployments"). For each found, we output the content of .metadata.name followed by a literal colon and a space. Then we iterate again over all .spec.template.spec.containers[].students[], perform the pattern test and concatenate the outcome.

To print out raw strings instead of JSON, we use the -r option when calling jq.

kubectl get deployments -o json \
| jq --arg pattern "Jeff" -r '
    .items[]
    | .metadata.name + ": " + (
        .spec.template.spec.containers[].students[]
        | select(test($pattern))
      )
  '
-- pmf
Source: StackOverflow

9/20/2021

To retrieve the "students" array(s) in the input, you could use this filter:

.items[]
| paths(objects) as $p
| getpath($p)
| select( objects | has("students") )
| .students

You can then add additional filters to select the particular student(s) of interest, e.g.

| .[]
| select(test("Jeff"))

And then add any postprocessing filters, e.g.

| "student-deployment: \(.)"

Of course you can obtain the students array in numerous other ways.

-- peak
Source: StackOverflow