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'