I'm trying to figure out how to print name of keys and specific sub-sub values from it. My JSON is:
{
"results": 3,
"rows": [
{
"hostname1": {
"tags": [
"owner:TEAM_A",
"friendlyname:myhost1",
"x:abc",
"y:jkl"
]
}
},
{
"hostname2": {
"tags": [
"friendlyname:myhost2",
"owner:TEAM_A",
"x:def",
"q:jkl"
]
}
},
{
"hostname3": {
"tags": [
"owner:TEAM_A",
"x:ghi",
"friendlyname:myhost3",
"q:jkl"
]
}
}
]
}
What I've already achieved is to print just keys of hostnames:
jq -r '.rows[] | keys[]' example.json
hostname1
hostname2
hostname3
I know how to print key:values from tags array:
jq -r .rows[0].hostname1.tags[0,1] example.json
owner:TEAM_A
friendlyname:myhost1
But I can't figure out how to print
hostname1
"owner:TEAM_A",
"friendlyname:myhost1",
hostname2
"owner:TEAM_A",
"friendlyname:myhost2",
hostname3
"owner:TEAM_A",
"friendlyname:myhost3",
Be aware, that the keys in tags array has different order, so I cannot reach it through .rows[0].hostname1.tags[0,1]
I'm looking for something like .rows[0].all_keys.tags[owner,friendlyname]
My bash script was very close, but the order of keys brokes it.
hostnames=`jq -r '.rows[] | keys[]' example.json`
count=0
for i in $hostnames
do
jq -r .rows[$count].$i\.tags[0,1] example.json
echo $i
((count=count 1))
done
CodePudding user response:
You can use to_entries
to convert an object into an array of key-value pairs, then access .key
and .value
of its items to your own likings. For instance:
jq -r '.rows[] | to_entries[] | [.key, .value.tags[0,1]] | join("\n ")'
hostname1
owner:TEAM_A
friendlyname:myhost1
hostname2
friendlyname:myhost2
owner:TEAM_A
hostname3
owner:TEAM_A
x:ghi
Another example:
jq -r '
.rows[] | to_entries[] | [.key, (
.value.tags[] | select(startswith("owner:", "friendlyname:"))
)] | join("\n ")
'
hostname1
owner:TEAM_A
friendlyname:myhost1
hostname2
friendlyname:myhost2
owner:TEAM_A
hostname3
owner:TEAM_A
friendlyname:myhost3
CodePudding user response:
Turning tags
into an object first would make it easier to retrieve tags in a particular order.
.rows[][].tags | INDEX(sub(":.*"; "")) | .owner, .friendlyname
And it seems like you don't need a shell loop for this task, JQ can do all that and even more on its own.
.rows[]
| keys_unsorted[] as $hostname
| .[$hostname].tags
| INDEX(sub(":.*"; ""))
| $hostname, "\t" (.owner, .friendlyname)