Tuesday, October 25, 2022

[SOLVED] Turn output of command into valid json?

Issue

How can I use bash commands to convert the output of 'kubectl cluster-info dump' into valid json?

As is, right now, it comes out like this (extremely abbreviated):

{
    "selfLink": "/api/v1/nodes",
    "resourceVersion": "24393",
    "Items": [tons of json]
}
{
    "selfLink": "/api/v1/namespaces/default/events",
    "resourceVersion": "24393",
    "Items": [tons of json]
}
...
{
    "selfLink": "/api/v1/namespaces/default/pods",
    "resourceVersion": "24393",
    "Items": [tons of json]
}

I would like to pipe the output of this command through sed or awk to translate this output into valid json, something like:

[{"k","v","k2","v2"},
 {"k","v","k2","v2"},
 ...
 {"k","v","k2","v2"}]

which I can then easily parse with json parsers like jq


Solution

If the layout is as shown, then:

kubectl cluster-info dump |
{ echo "["; sed -e 's/^}$/},/' -e '$s/^},$/}/'; echo "]"; }

would do the job. This relies on the "tons of JSON" not having any line containing only } in the middle. Since JSON parsers aren't worried by spaces and newlines, there's no need to do more.

You can avoid the shell { …; } notation with:

kubectl cluster-info dump |
sed -e '1s/^/[/' -e 's/^}$/},/' -e '$s/^},$/}]/'

The first sed commands adds a [ to the start of the first line; the second changes each line consisting of just } to }, (including the last line), but the third undoes that damage and adds the ] instead.

You could even combine those -e commands into one separated by semicolons. Personally, I prefer separate -e options to make it easer to read. If they're more complex, I put each one on its own line, with backslash to continue the overall command over multiple lines.



Answered By - Jonathan Leffler
Answer Checked By - Mary Flores (WPSolving Volunteer)