Posts on tag: shell
tablizer - a tool to manipulate tabular output of shell commands
Last year I switched departments and am working now with k8s, the cloud and all the new fancy stuff. Most of the time I work on the commandline. I cannot say I am not happy with the new assignment, but some things k8s annoy me anyway.
Here’s an example:
kgpw|grep 5fc
connecttest10-pgbenchclient-5fcb6888c9-28csx 0/1 ContainerCreating 0 8d <none> kind-worker2 <none> <none>
connecttest10-pgbenchclient-5fcb6888c9-4cbh4 0/1 ContainerCreating 0 8d <none> kind-worker3 <none> <none>
connecttest10-pgbenchclient-5fcb6888c9-bh644 0/1 ContainerCreating 0 8d <none> kind-worker3 <none> <none>
connecttest10-pgbenchclient-5fcb6888c9-bp9sf 0/1 ContainerCreating 0 8d <none> kind-worker2 <none> <none>
connecttest10-pgbenchclient-5fcb6888c9-lw8kp 0/1 ContainerCreating 0 8d <none> kind-worker3 <none> <none>
(kgpw
== kubectl get pod -o wide
)
The first problem is, that this output is waaaay to wide. Sometimes I get outputs which so wide, that even on a 3440x1440 monitor every line is being broken. The result is unreadable. I even once deleted the wrong database just because of this mess.
The other issue is that if you use something like |grep
then the
headers go missing as can be seen in the example above.
I hate this fucking behavior.
Of course, it might be possible to circumvent all these (and more)
issues using tools like awk
etc. And to make it clear: i tried this
in the beginning. But the shell function I used for this purpose got
more and more unflexible, it grew larger and larger up to the point
that it wasn’t maintainable anymore.
Enter tablizer.
Since working in the cloud, learning Go was a must anyway. And I am a practical learner, that is I need some usefull project to learn a new language. This annoyance here came in to the “rescue”.
By using tablizer
I can combine tools like egrep, awk, sed, sort and
column in one handy and easy to use tool. I don’t use it directly most
of the time, but rather put it into handy shell aliases.
Here’s the usage message of it:
Usage:
tablizer [regex] [file, ...] [flags]
Operational Flags:
-c, --columns string Only show the speficied columns (separated by ,)
-v, --invert-match select non-matching rows
-n, --no-numbering Disable header numbering
-N, --no-color Disable pattern highlighting
-H, --no-headers Disable headers display
-s, --separator string Custom field separator
-k, --sort-by int Sort by column (default: 1)
Output Flags (mutually exclusive):
-X, --extended Enable extended output
-M, --markdown Enable markdown table output
-O, --orgtbl Enable org-mode table output
-S, --shell Enable shell evaluable ouput
-Y, --yaml Enable yaml output
-C, --csv Enable CSV output
-A, --ascii Default output mode, ascii tabular
Sort Mode Flags (mutually exclusive):
-a, --sort-age sort according to age (duration) string
-D, --sort-desc Sort in descending order (default: ascending)
-i, --sort-numeric sort according to string numerical value
-t, --sort-time sort according to time string
Other Flags:
--completion <shell> Generate the autocompletion script for <shell>
-d, --debug Enable debugging
-h, --help help for tablizer
-m, --man Display manual page
-v, --version Print program version
So, let’s work through an example. Say we want to get a list of pods, their status and the node each pod is running on AND only pods matching some pattern shall be printed.
The very first thing you do, is execute the original command again
(without any |grep
after it!) and put | tablizer
behind it. You’ll
get something like this (shortened):
kgpw | tablizer
NAME(1) READY(2) STATUS(3) RESTARTS(4) AGE(5) IP(6) NODE(7) NOMINATED NODE(8) READINESS GATES(9)
connect11test10-benchtest-pgbenchclient-b68d988b8-9vks5 0/1 ContainerCreating 0 7d6h <none> kind-worker3 <none> <none>
connect11test10-benchtest-pgbenchclient-b68d988b8-dpq8g 0/1 ContainerCreating 0 7d6h <none> kind-worker2 <none> <none>
connect11test10-benchtest-pgbenchclient-b68d988b8-f2dpn 0/1 ContainerCreating 0 7d6h <none> kind-worker3 <none> <none>
connect11test10-benchtest-pgbenchclient-b68d988b8-fjhk4 0/1 ContainerCreating 0 7d6h <none> kind-worker2 <none> <none>
connect11test10-benchtest-pgbenchclient-b68d988b8-m64z7 0/1 ContainerCreating 0 7d6h <none> kind-worker2 <none> <none>
[..]
This looks pretty unchanged to the original output, but the headers
are now numerized. Armed with that knowledge we can now reduce the
output to the columns we want to see by using the -c
option:
kgpw | tablizer -c 1,3,7
NAME(1) STATUS(3) NODE(7)
connect11test10-benchtest-pgbenchclient-b68d988b8-9vks5 ContainerCreating kind-worker3
connect11test10-benchtest-pgbenchclient-b68d988b8-dpq8g ContainerCreating kind-worker2
connect11test10-benchtest-pgbenchclient-b68d988b8-f2dpn ContainerCreating kind-worker3
connect11test10-benchtest-pgbenchclient-b68d988b8-fjhk4 ContainerCreating kind-worker2
connect11test10-benchtest-pgbenchclient-b68d988b8-m64z7 ContainerCreating kind-worker2
connecttest10-benchtest-pgbenchclient-8bb8ff5d8-52xg5 ContainerCreating kind-worker3
Now we add our search pattern and we also add -n
to hide the numberization:
kgpw|tablizer -c 1,3,7 -n 5fc
NAME STATUS NODE
connecttest10-pgbenchclient-5fcb6888c9-28csx ContainerCreating kind-worker2
connecttest10-pgbenchclient-5fcb6888c9-4cbh4 ContainerCreating kind-worker3
connecttest10-pgbenchclient-5fcb6888c9-bh644 ContainerCreating kind-worker3
connecttest10-pgbenchclient-5fcb6888c9-bp9sf ContainerCreating kind-worker2
connecttest10-pgbenchclient-5fcb6888c9-lw8kp ContainerCreating kind-worker3
That’s pretty much it. Now put this commandline into some handy alias
and you’re good to go. There are many more options: you can let
tablizer
generate markdown or orgmode tables, you can let it print
extended output like \x
in psql
, yaml mode etc etc. There are
usefull sorting options, you can even sort by kubernetes age output.
Also, you’re not limited to shell output, using the -s
option you
can use the tool to process CSV files (or anything other looking
tabular with headers), you can also generate valid CSV for that
matter.
If you’re working on the commandline every day in a cloud environment and are annoyed by too large and confusing outputs, then give tablizer a try. It’s easy to install, there are precompiled binaries for the most popular architectures without dependencies. There are also tarballs containing a proper installer with a manual page if you’re into this.