Jtbl
CLI tool to convert JSON and JSON Lines to terminal, CSV, HTTP, and markdown tables
Install / Use
/learn @kellyjonbrazil/JtblREADME
jtbl
A simple cli tool to print JSON data as a table in the terminal.
jtbl accepts piped JSON data from stdin and outputs a text table representation to stdout. e.g:
$ cat cities.json | jtbl
LatD LatM LatS NS LonD LonM LonS EW City State
------ ------ ------ ---- ------ ------ ------ ---- ----------------- -------
41 5 59 N 80 39 0 W Youngstown OH
42 52 48 N 97 23 23 W Yankton SD
46 35 59 N 120 30 36 W Yakima WA
42 16 12 N 71 48 0 W Worcester MA
43 37 48 N 89 46 11 W Wisconsin Dells WI
36 5 59 N 80 15 0 W Winston-Salem NC
49 52 48 N 97 9 0 W Winnipeg MB
jtbl expects a JSON array of JSON objects or JSON Lines.
It can be useful to JSONify command line output with jc, filter through a tool like jq, and present in jtbl:
$ jc ifconfig | jq -c '.[] | {name, type, ipv4_addr, ipv4_mask}'| jtbl
name type ipv4_addr ipv4_mask
------- -------------- -------------- -------------
docker0 Ethernet 172.17.0.1 255.255.0.0
ens33 Ethernet 192.168.71.146 255.255.255.0
lo Local Loopback 127.0.0.1 255.0.0.0
Installation
You can install jtbl via pip, via OS Package Repositories, MSI installer for Windows, or by downloading the correct binary for your architecture and running it anywhere on your filesystem.
Pip (macOS, linux, unix, Windows)
For the most up-to-date version and the most cross-platform option, use pip or pip3 to download and install jtbl directly from PyPi:
pip3 install jtbl
OS Packages
See Releases on Github for MSI packages and binaries.
Usage
Just pipe JSON data to jtbl. (e.g. cat a JSON file, jc, jq, aws cli, kubectl, etc.)
$ <JSON Data> | jtbl [OPTIONS]
Options
--cols=nmanually configure the terminal width-c,--csvCSV table output-d,--dokuwikiDokuwiki table output-f,--fancyfancy table output-h,--helpprints help information-H,--htmlHTML table output-m,--markdownmarkdown table output-n,--no-wrapno data wrapping if too long for the terminal width (overrides--colsand-t)-q,--quietdon't print error messages to STDERR-r,--rotaterotate the data (each row turns into a table of key/value pairs)-t,--truncatetruncate data instead of wrapping if too long for the terminal width-v,--versionprints version information
Compatible JSON Formats
jtbl works best with a shallow array of JSON objects. Each object should have a few elements that will be turned into table columns. Fortunately, this is how many APIs present their data.
JSON Array Example
[
{
"unit": "proc-sys-fs-binfmt_misc.automount",
"load": "loaded",
"active": "active",
"sub": "waiting",
"description": "Arbitrary Executable File Formats File System Automount Point"
},
{
"unit": "sys-devices-pci0000:00-0000:00:07.1-ata2-host2-target2:0:0-2:0:0:0-block-sr0.device",
"load": "loaded",
"active": "active",
"sub": "plugged",
"description": "VMware_Virtual_IDE_CDROM_Drive"
},
...
]
jtbl can also work with JSON Lines format with similar features.
JSON Lines Example
{"name": "docker0", type": "Ethernet", "ipv4_addr": "172.17.0.1", "ipv4_mask": "255.255.0.0"}
{"name": "ens33", "type": "Ethernet", "ipv4_addr": "192.168.71.146", "ipv4_mask": "255.255.255.0"}
{"name": "lo", "type": "Local Loopback", "ipv4_addr": "127.0.0.1", "ipv4_mask": "255.0.0.0"}
...
Filtering the JSON Input
If there are too many elements, or the data in the elements are too large, the table may not fit in the terminal screen. In this case you can use a JSON filter like jq or jello to send jtbl only the elements you are interested in:
jq Array Method
The following example uses jq to filter and format the filtered elements into a proper JSON array.
$ cat /etc/passwd | jc --passwd | jq '[.[] | {username, shell}]'
[
{
"username": "root",
"shell": "/bin/bash"
},
{
"username": "bin",
"shell": "/sbin/nologin"
},
{
"username": "daemon",
"shell": "/sbin/nologin"
},
...
]
(Notice the square brackets around the filter)
jq Slurp Method
The following example uses jq to filter and 'slurp' the filtered elements into a proper JSON array.
$ cat /etc/passwd | jc --passwd | jq '.[] | {username, shell}' | jq -s
[
{
"username": "root",
"shell": "/bin/bash"
},
{
"username": "bin",
"shell": "/sbin/nologin"
},
{
"username": "daemon",
"shell": "/sbin/nologin"
},
...
]
(Notice the jq -s at the end)
jq JSON Lines Method
The following example will send the data in JSON Lines format, which jtbl can understand:
$ cat /etc/passwd | jc --passwd | jq -c '.[] | {username, shell}'
{"username":"root","shell":"/bin/bash"}
{"username":"bin","shell":"/sbin/nologin"}
{"username":"daemon","shell":"/sbin/nologin"}
...
(Notice the -c option being used)
jello List Comprehension Method
If you prefer python list and dictionary syntax to filter JSON data, you can use jello:
$ cat /etc/passwd | jc --passwd | jello '[{"username": x.username, "shell": x.shell} for x in _]'
[
{
"username": "root",
"shell": "/bin/bash"
},
{
"username": "bin",
"shell": "/sbin/nologin"
},
{
"username": "daemon",
"shell": "/sbin/nologin"
},
...
]
When piping any of these to jtbl you get the following result:
$ cat /etc/passwd | jc --passwd | jello '[{"username": x.username, "shell": x.shell} for x in _]' | jtbl
username shell
--------------- --------------
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
...
Working with Deeper JSON Structures
jtbl will happily dump deeply nested JSON structures into a table, but usually this is not what you are looking for.
$ jc dig www.cnn.com | jtbl
╒══════════╤══════════╤═══════╤════════════╤═════════════╤══════════════╤══════════════╤══════════════╤══════════════╤════════════╤════════════╤══════════════╤════════════╤════════════╤════════╤══════════════╤══════════════╕
│ opcode │ status │ id │ flags │ query_num │ answer_num │ authority_ │ additional │ opt_pseudo │ question │ answer │ query_time │ server │ when │ rcvd │ when_epoch │ when_epoch │
│ │ │ │ │ │ │ num │ _num │ section │ │ │ │ │ │ │ │ _utc │
╞══════════╪══════════╪═══════╪════════════╪═════════════╪══════════════╪══════════════╪══════════════╪══════════════╪════════════╪════════════╪══════════════╪════════════╪════════════╪════════╪══════════════╪══════════════╡
│ QUERY │ NOERROR │ 36494 │ ['qr', 'rd │ 1 │ 4 │ 0 │ 1 │ {'edns': { │ {'name': ' │ [{'name': │ 47 │ 2600:1700: │ Wed Dec 22 │ 100 │ 1640200072 │ │
│ │ │ │ ', 'ra'] │ │ │ │ │ 'version': │ cnn.com.', │ 'cnn.com.' │ │ bab0:d40:: │ 11:07:52 │ │ │ │
│ │ │ │ │ │ │ │ │ 0, 'flags │ 'class': │ , 'class': │ │ 1#53(2600: │ PST 2021 │ │ │ │
│ │ │ │ │ │ │ │ │ ': [], 'ud │ 'IN', 'typ │ 'IN', 'ty │ │ 1700:bab0: │ │ │ │ │
│ │ │ │ │ │ │ │ │ p': 4096}} │ e': 'A'} │ pe': 'A', │ │ d40::1) │ │ │ │ │
│ │ │ │ │ │ │ │ │ │ │ 'ttl': 60, │ │ │ │ │ │ │
│ │ │ │ │ │ │ │ │ │ │ 'data': ' │ │ │ │ │ │ │
│ │ │ │ │ │ │ │ │ │ │ 151.101.12 │ │ │ │ │ │ │
│ │ │ │ │ │ │ │ │ │ │ 9.67'}, {' │ │ │ │ │ │ │
│ │ │ │ │ │ │ │ │ │ │ name': 'cn │ │ │ │ │
