How to parse the json to retrieve a field from output of
kubectl get pods -o json
From the command line I need to obtain the system generated container name from a google cloud cluster ... Here are the salient bits of json output from above command :
click here to see entire json output
So the top most json key is an array : items[] followed by metadata.labels.name where the search critera value of that compound key is "web" (see above image green marks). On a match, I then need to retrieve field
.items[].metadata.name
which so happens to have value :
web-controller-5e6ij // I need to retrieve this value
Here are docs on jsonpath
I want to avoid text parsing output of
kubectl get pods
which is
NAME READY STATUS RESTARTS AGE
mongo-controller-h714w 1/1 Running 0 12m
web-controller-5e6ij 1/1 Running 0 9m
Following will correctly parse this get pods
command yet I feel its too fragile
kubectl get pods | tail -1 | cut -d' ' -f1
JsonPath expressions always refer to a JSON structure in the same way as XPath expression are used in combination with an XML document. The "root member object" in JsonPath is always referred to as $ regardless if it is an object or array. JsonPath expressions can use the dot–notation.
You use a JSONPath expression to traverse the path to an element in the JSON structure. You start at the root node or element, represented by $, and reach the required element in the JSON structure to extract data from it. You can use either the dot-notation or the bracket-notation to form the expressions.
Kubectl uses JSONPath expressions to filter on specific fields in the JSON object and format the output. In addition to the original JSONPath template syntax, the following functions and syntax are valid: Use double quotes to quote text inside JSONPath expressions.
jq is a command-line JSON processor. It works like sed for JSON data; you can use it to filter, parse, and transform structured data with the same ease that sed , awk , or grep let you do with raw text.
After much battling this one liner does retrieve the container name :
kubectl get pods -o=jsonpath='{.items[?(@.metadata.labels.name=="web")].metadata.name}'
when this is the known search criteria :
items[].metadata.labels.name == "web"
and this is the desired field to retrieve
items[].metadata.name : "web-controller-5e6ij"
If you want to filter by labels. You could just use the kubectl -l
flag. The following will do the same:
kubectl get pods -l name=web -o=jsonpath='{.items..metadata.name}'
In addition to Scott Stensland answer, a way to format your results:
kubectl get pods -o=jsonpath='{range .items[?(@.metadata.labels.name=="web")]}{.metadata.name}{"/n"}'
This add newlines. You can also do {", "} to output comma with space.
Another solution:
Use JQ to get a nicely formatted json result:
kubectl get pods -o json | jq -r '.items[] | [filter] | [formatted result]' | jq -s '.'
Example of [filter]:
select(.metadata.labels.name=="web")
Example of [formatted result] (you can add more fields if your want):
{name: .metadata.name}
jq -s '.', for putting result objects in array.
To wrap it up:
kubectl get pods -o json | jq -r '.items[] | select(.metadata.labels.name=="web") | {name: .metadata.name}' | jq -s '.'
Then afterwards you can use this json data to get the desired output result.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With