I'd like to pretty print the ip addresses and show the output in in tabular format, including all the meta data such as valid_lft, temporary, etc.
I figured out that ip -j addr show eth0 is giving me the JSON I need.
If I run ip -j addr show eth0 | jq -r '.[0].addr_info' the data is already filtered for what I'm interested in:
[
{
"family": "inet",
"local": "192.168.x.y",
"prefixlen": 24,
"broadcast": "192.168.1.255",
"scope": "global",
"dynamic": true,
"noprefixroute": true,
"label": "eth0",
"valid_life_time": 2339,
"preferred_life_time": 2339
},
{
"family": "inet6",
"local": "2003:mm:nn:pp:ww:xx:yy:zz",
"prefixlen": 64,
"scope": "global",
"temporary": true,
"dynamic": true,
"valid_life_time": 14342,
"preferred_life_time": 1742
},
{
"family": "inet6",
"local": "2003:mm:nn:pp:qq:rr:ss:tt",
"prefixlen": 64,
"scope": "global",
"dynamic": true,
"mngtmpaddr": true,
"noprefixroute": true,
"valid_life_time": 14342,
"preferred_life_time": 1742
},
{
"family": "inet6",
"local": "fd4e:gg:hh:ii:jj:kk:ll:mm",
"prefixlen": 64,
"scope": "global",
"temporary": true,
"dynamic": true,
"valid_life_time": 14342,
"preferred_life_time": 1742
},
{
"family": "inet6",
"local": "fd4e:gg:hh:ii:qq:rr:ss:tt",
"prefixlen": 64,
"scope": "global",
"dynamic": true,
"mngtmpaddr": true,
"noprefixroute": true,
"valid_life_time": 14342,
"preferred_life_time": 1742
},
{
"family": "inet6",
"local": "fe80::qq:rr:ss:tt",
"prefixlen": 64,
"scope": "link",
"noprefixroute": true,
"valid_life_time": 4294967295,
"preferred_life_time": 4294967295
}
]
I know that I can use @tsv to get a table format and to accommodate for different value lengths I can pipe to column -ts $'\t'.
What I cannot figure out is how I can iterate through all the objects and extract the keys first, because if I don't do that, the output values will be in incorrect columns, based on what keys each of the object has (or rather not has). I already succeeded in extracted the keys using
$ ip -j addr show eth0 | jq -r '[.[0].addr_info | .[] | keys_unsorted[]] | reduce .[] as $a ([]; if IN(.[]; $a) then . else . += [$a] end)'
[
"family",
"local",
"prefixlen",
"broadcast",
"scope",
"dynamic",
"noprefixroute",
"label",
"valid_life_time",
"preferred_life_time",
"temporary",
"mngtmpaddr"
]
Now I do not know how to combine all of this.
Essentially, the following is yielding the desired result, but I do not like it, because the headers/keys are manually defined:
$ ip -j addr show eth0 | jq -r '(["Family", "Local", "Prefixlen", "Broadcast", "Scope", "Dynamic", "Noprefixroute", "Label", "Valid_Life_Time", "Preferred_Life_Time", "Temporary", "Deprecated", "Mngtmpaddr"] | (., map(length*"-"))), (.[0].addr_info | .[] | [ .family, .local, .prefixlen, .broadcast, .scope, .dynamic, .noprefixroute, .label, .valid_life_time, .preferred_life_time, .temporary, .deprecated, .mngtmpaddr ] | map(.//"-")) | @tsv' | column -ts $'\t'
Family Local Prefixlen Broadcast Scope Dynamic Noprefixroute Label Valid_Life_Time Preferred_Life_Time Temporary Deprecated Mngtmpaddr
------ ----- --------- --------- ----- ------- ------------- ----- --------------- ------------------- --------- ---------- ----------
inet 192.168.x.y 24 192.168.1.255 global true true eth0 1917 1917 - - -
inet6 2003:mm:nn:pp:ww:xx:yy:zz 64 - global true - - 14348 1748 true - -
inet6 2003:mm:nn:pp:qq:rr:ss:tt 64 - global true true - 14348 1748 - - true
inet6 fd4e:gg:hh:ii:jj:kk:ll:mm 64 - global true - - 14348 1748 true - -
inet6 fd4e:gg:hh:ii:qq:rr:ss:tt 64 - global true true - 14348 1748 - - true
inet6 fe80::qq:rr:ss:tt 64 - link - true - 4294967295 4294967295 - - -
Any help is much appreciated.
ip -j addr show eth0 | jq -c '.[].addr_info' | mlr --j2p unsparsify(or--j2tfor JSON to TSV instead of to pretty)ip -j addr show | jq -c '.[].addr_info' | vd -f json(vdcan be found in thevisidatapackage on Debian-based systems at least)ip -j a | jq -r '[.[].addr_info[]]|add|keys_unsorted'