From dd13300c8b9aaf52802f764d86a59053ecb6c53e Mon Sep 17 00:00:00 2001 From: Thomas von Dein Date: Tue, 4 Oct 2022 15:25:22 +0200 Subject: [PATCH] add manpage to source (regen @ make) --- Makefile | 2 +- cmd/tablizer.go | 128 ++++++++++++++++++++++ tablizer.1 | 277 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 406 insertions(+), 1 deletion(-) create mode 100644 cmd/tablizer.go create mode 100644 tablizer.1 diff --git a/Makefile b/Makefile index f16c146..f106b40 100644 --- a/Makefile +++ b/Makefile @@ -53,7 +53,7 @@ install: buildlocal install -o $(UID) -g $(GID) -m 444 $(tool).1 $(PREFIX)/man/man1/ clean: - rm -rf $(tool) $(tool).1 cmd/$(tool).go releases + rm -rf $(tool) releases test: go test -v ./... diff --git a/cmd/tablizer.go b/cmd/tablizer.go new file mode 100644 index 0000000..f7e26ad --- /dev/null +++ b/cmd/tablizer.go @@ -0,0 +1,128 @@ +package cmd +var manpage = ` +NAME + tablizer - Manipulate tabular output of other programs + +SYNOPSIS + Usage: + tablizer [regex] [file, ...] [flags] + + Flags: + -c, --columns string Only show the speficied columns (separated by ,) + -d, --debug Enable debugging + -h, --help help for tablizer + -n, --no-numbering Disable header numbering + -o, --output string Output mode - one of: orgtbl, markdown, extended, ascii(default) + -X, --extended Enable extended output + -M, --markdown Enable markdown table output + -O, --orgtbl Enable org-mode table output + -s, --separator string Custom field separator + -v, --version Print program version + +DESCRIPTION + Many programs generate tabular output. But sometimes you need to + post-process these tables, you may need to remove one or more columns or + you may want to filter for some pattern or you may need the output in + another program and need to parse it somehow. Standard unix tools such + as awk(1), grep(1) or column(1) may help, but sometimes it's a tedious + business. + + Let's take the output of the tool kubectl. It contains cells with + withespace and they do not separate columns by TAB characters. This is + not easy to process. + + You can use tablizer to do these and more things. + + tablizer analyses the header fiels of a table, registers the column + positions of each header field and separates columns by those positions. + + Without any options it reads its input from "STDIN", but you can also + specify a file as a parameter. If you want to reduce the output by some + regular expression, just specify it as its first parameters. Hence: + + # read from STDIN + kubectl get pods | tablizer + + # read a file + tablizer filename + + # search for pattern in a file (works like grep) + tablizer regex filename + + # search for pattern in STDIN + kubectl get pods | tablizer regex + + The output looks like the original one but every header field will have + a numer associated with it, e.g.: + + NAME(1) READY(2) STATUS(3) RESTARTS(4) AGE(5) + + These numbers denote the column and you can use them to specify which + columns you want to have in your output: + + kubectl get pods | tablizer -c1,3 + + You can specify the numbers in any order but output will always follow + the original order. + + The numbering can be suppressed by using the -n option. + + Finally the -d option enables debugging output which is mostly usefull + for the developer. + + OUTPUT MODES + There might be cases when the tabular output of a program is way too + large for your current terminal but you still need to see every column. + In such cases the -o extended or -X option can be usefull which enables + *extended mode*. In this mode, each row will be printed vertically, + header left, value right, aligned by the field widths. Here's an + example: + + kubectl get pods | ./tablizer -o extended + NAME: repldepl-7bcd8d5b64-7zq4l + READY: 1/1 + STATUS: Running + RESTARTS: 1 (71m ago) + AGE: 5h28m + + You can of course still use a regex to reduce the number of rows + displayed. + + The option -o shell can be used if the output has to be processed by the + shell, it prints variable assignments for each cell, one line per row: + + kubectl get pods | ./tablizer -o extended ./tablizer -o shell + NAME="repldepl-7bcd8d5b64-7zq4l" READY="1/1" STATUS="Running" RESTARTS="9 (47m ago)" AGE="4d23h" + NAME="repldepl-7bcd8d5b64-m48n8" READY="1/1" STATUS="Running" RESTARTS="9 (47m ago)" AGE="4d23h" + NAME="repldepl-7bcd8d5b64-q2bf4" READY="1/1" STATUS="Running" RESTARTS="9 (47m ago)" AGE="4d23h" + + You can use this in an eval loop. + + Beside normal ascii mode (the default) and extended mode there are more + output modes available: orgtbl which prints an Emacs org-mode table and + markdown which prints a Markdown table. + +BUGS + In order to report a bug, unexpected behavior, feature requests or to + submit a patch, please open an issue on github: + . + +LICENSE + This software is licensed under the GNU GENERAL PUBLIC LICENSE version + 3. + + Copyright (c) 2022 by Thomas von Dein + + This software uses the following GO libraries: + + repr (https://github.com/alecthomas/repr) + Released under the MIT License, Copyright (c) 2016 Alec Thomas + + cobra (https://github.com/spf13/cobra) + Released under the Apache 2.0 license, Copyright 2013-2022 The Cobra + Authors + +AUTHORS + Thomas von Dein tom AT vondein DOT org + +` diff --git a/tablizer.1 b/tablizer.1 new file mode 100644 index 0000000..92a1660 --- /dev/null +++ b/tablizer.1 @@ -0,0 +1,277 @@ +.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.42) +.\" +.\" Standard preamble: +.\" ======================================================================== +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R +.fi +.. +.\" Set up some character translations and predefined strings. \*(-- will +.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +.\" double quote, and \*(R" will give a right double quote. \*(C+ will +.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +.\" nothing in troff, for use with C<>. +.tr \(*W- +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.ie n \{\ +. ds -- \(*W- +. ds PI pi +. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +. ds L" "" +. ds R" "" +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds -- \|\(em\| +. ds PI \(*p +. ds L" `` +. ds R" '' +. ds C` +. ds C' +'br\} +.\" +.\" Escape single quotes in literal strings from groff's Unicode transform. +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" +.\" If the F register is >0, we'll generate index entries on stderr for +.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +.\" entries marked with X<> in POD. Of course, you'll have to process the +.\" output yourself in some meaningful fashion. +.\" +.\" Avoid warning from groff about undefined register 'F'. +.de IX +.. +.nr rF 0 +.if \n(.g .if rF .nr rF 1 +.if (\n(rF:(\n(.g==0)) \{\ +. if \nF \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. if !\nF==2 \{\ +. nr % 0 +. nr F 2 +. \} +. \} +.\} +.rr rF +.\" +.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +.\" Fear. Run. Save yourself. No user-serviceable parts. +. \" fudge factors for nroff and troff +.if n \{\ +. ds #H 0 +. ds #V .8m +. ds #F .3m +. ds #[ \f1 +. ds #] \fP +.\} +.if t \{\ +. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +. ds #V .6m +. ds #F 0 +. ds #[ \& +. ds #] \& +.\} +. \" simple accents for nroff and troff +.if n \{\ +. ds ' \& +. ds ` \& +. ds ^ \& +. ds , \& +. ds ~ ~ +. ds / +.\} +.if t \{\ +. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +.\} +. \" troff and (daisy-wheel) nroff accents +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +.ds ae a\h'-(\w'a'u*4/10)'e +.ds Ae A\h'-(\w'A'u*4/10)'E +. \" corrections for vroff +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +. \" for low resolution devices (crt and lpr) +.if \n(.H>23 .if \n(.V>19 \ +\{\ +. ds : e +. ds 8 ss +. ds o a +. ds d- d\h'-1'\(ga +. ds D- D\h'-1'\(hy +. ds th \o'bp' +. ds Th \o'LP' +. ds ae ae +. ds Ae AE +.\} +.rm #[ #] #H #V #F C +.\" ======================================================================== +.\" +.IX Title "TABLIZER 1" +.TH TABLIZER 1 "2022-10-04" "1" "User Commands" +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.if n .ad l +.nh +.SH "NAME" +tablizer \- Manipulate tabular output of other programs +.SH "SYNOPSIS" +.IX Header "SYNOPSIS" +.Vb 2 +\& Usage: +\& tablizer [regex] [file, ...] [flags] +\& +\& Flags: +\& \-c, \-\-columns string Only show the speficied columns (separated by ,) +\& \-d, \-\-debug Enable debugging +\& \-h, \-\-help help for tablizer +\& \-n, \-\-no\-numbering Disable header numbering +\& \-o, \-\-output string Output mode \- one of: orgtbl, markdown, extended, ascii(default) +\& \-X, \-\-extended Enable extended output +\& \-M, \-\-markdown Enable markdown table output +\& \-O, \-\-orgtbl Enable org\-mode table output +\& \-s, \-\-separator string Custom field separator +\& \-v, \-\-version Print program version +.Ve +.SH "DESCRIPTION" +.IX Header "DESCRIPTION" +Many programs generate tabular output. But sometimes you need to +post-process these tables, you may need to remove one or more columns +or you may want to filter for some pattern or you may need the output +in another program and need to parse it somehow. Standard unix tools +such as \fBawk\fR\|(1), \fBgrep\fR\|(1) or \fBcolumn\fR\|(1) may help, but sometimes it's a +tedious business. +.PP +Let's take the output of the tool kubectl. It contains cells with +withespace and they do not separate columns by \s-1TAB\s0 characters. This is +not easy to process. +.PP +You can use \fBtablizer\fR to do these and more things. +.PP +\&\fBtablizer\fR analyses the header fiels of a table, registers the column +positions of each header field and separates columns by those +positions. +.PP +Without any options it reads its input from \f(CW\*(C`STDIN\*(C'\fR, but you can also +specify a file as a parameter. If you want to reduce the output by +some regular expression, just specify it as its first +parameters. Hence: +.PP +.Vb 2 +\& # read from STDIN +\& kubectl get pods | tablizer +\& +\& # read a file +\& tablizer filename +\& +\& # search for pattern in a file (works like grep) +\& tablizer regex filename +\& +\& # search for pattern in STDIN +\& kubectl get pods | tablizer regex +.Ve +.PP +The output looks like the original one but every header field will +have a numer associated with it, e.g.: +.PP +.Vb 1 +\& NAME(1) READY(2) STATUS(3) RESTARTS(4) AGE(5) +.Ve +.PP +These numbers denote the column and you can use them to specify which +columns you want to have in your output: +.PP +.Vb 1 +\& kubectl get pods | tablizer \-c1,3 +.Ve +.PP +You can specify the numbers in any order but output will always follow +the original order. +.PP +The numbering can be suppressed by using the \fB\-n\fR option. +.PP +Finally the \fB\-d\fR option enables debugging output which is mostly +usefull for the developer. +.SS "\s-1OUTPUT MODES\s0" +.IX Subsection "OUTPUT MODES" +There might be cases when the tabular output of a program is way too +large for your current terminal but you still need to see every +column. In such cases the \fB\-o extended\fR or \fB\-X\fR option can be +usefull which enables \fIextended mode\fR. In this mode, each row will be +printed vertically, header left, value right, aligned by the field +widths. Here's an example: +.PP +.Vb 6 +\& kubectl get pods | ./tablizer \-o extended +\& NAME: repldepl\-7bcd8d5b64\-7zq4l +\& READY: 1/1 +\& STATUS: Running +\& RESTARTS: 1 (71m ago) +\& AGE: 5h28m +.Ve +.PP +You can of course still use a regex to reduce the number of rows +displayed. +.PP +The option \fB\-o shell\fR can be used if the output has to be processed +by the shell, it prints variable assignments for each cell, one line +per row: +.PP +.Vb 4 +\& kubectl get pods | ./tablizer \-o extended ./tablizer \-o shell +\& NAME="repldepl\-7bcd8d5b64\-7zq4l" READY="1/1" STATUS="Running" RESTARTS="9 (47m ago)" AGE="4d23h" +\& NAME="repldepl\-7bcd8d5b64\-m48n8" READY="1/1" STATUS="Running" RESTARTS="9 (47m ago)" AGE="4d23h" +\& NAME="repldepl\-7bcd8d5b64\-q2bf4" READY="1/1" STATUS="Running" RESTARTS="9 (47m ago)" AGE="4d23h" +.Ve +.PP +You can use this in an eval loop. +.PP +Beside normal ascii mode (the default) and extended mode there are +more output modes available: \fBorgtbl\fR which prints an Emacs org-mode +table and \fBmarkdown\fR which prints a Markdown table. +.SH "BUGS" +.IX Header "BUGS" +In order to report a bug, unexpected behavior, feature requests +or to submit a patch, please open an issue on github: +. +.SH "LICENSE" +.IX Header "LICENSE" +This software is licensed under the \s-1GNU GENERAL PUBLIC LICENSE\s0 version 3. +.PP +Copyright (c) 2022 by Thomas von Dein +.PP +This software uses the following \s-1GO\s0 libraries: +.IP "repr (https://github.com/alecthomas/repr)" 4 +.IX Item "repr (https://github.com/alecthomas/repr)" +Released under the \s-1MIT\s0 License, Copyright (c) 2016 Alec Thomas +.IP "cobra (https://github.com/spf13/cobra)" 4 +.IX Item "cobra (https://github.com/spf13/cobra)" +Released under the Apache 2.0 license, Copyright 2013\-2022 The Cobra Authors +.SH "AUTHORS" +.IX Header "AUTHORS" +Thomas von Dein \fBtom \s-1AT\s0 vondein \s-1DOT\s0 org\fR