Compare commits

..

7 Commits

Author SHA1 Message Date
T.v.Dein
5f3f7c417c Improve ascii table, add --ofs flag, enhance documentation (#67)
* enhanced documentation
* added --ofs parameter
  use 2 spaces for ascii output but it is customizable with --ofs,
  which is also being used by CSV mode (whose defaults remains unchanged)
* improve ascii table output, use 2 spaces as OFS by default
2025-09-30 11:21:49 +02:00
T.v.Dein
687f4b7bb2 Fix excess spaces on normal ascii table output (#66) 2025-09-29 20:46:33 +02:00
24b66b8a6b mv demo to top 2025-09-11 19:12:49 +02:00
d87c6878a4 bump version 2025-09-11 19:04:38 +02:00
4cdc4c8e18 switched to vhs demo creator 2025-09-11 19:04:02 +02:00
9cb9a66332 fix #64: documented -r parameter 2025-09-11 19:01:11 +02:00
24277cd716 use stdout if it is a tty 2025-09-11 19:00:37 +02:00
21 changed files with 529 additions and 455 deletions

View File

@@ -11,50 +11,58 @@ ignore certain column[s] by regex, name or number. It can output the
tabular data in a range of formats (see below). There's even an tabular data in a range of formats (see below). There's even an
interactive filter/selection tool available. interactive filter/selection tool available.
Usage: ## Demo
![demo cast](vhsdemo/demo.gif)
## Usage
```default ```default
Usage: Usage:
tablizer [regex,...] [file, ...] [flags] tablizer [regex,...] [file, ...] [flags]
Operational Flags: Operational Flags:
-c, --columns string Only show the speficied columns (separated by ,) -c, --columns string Only show the speficied columns (separated by ,)
-v, --invert-match select non-matching rows -v, --invert-match select non-matching rows
-n, --numbering Enable header numbering -n, --numbering Enable header numbering
-N, --no-color Disable pattern highlighting -N, --no-color Disable pattern highlighting
-H, --no-headers Disable headers display -H, --no-headers Disable headers display
-s, --separator string Custom field separator -s, --separator <string> Custom field separator
-k, --sort-by int|name Sort by column (default: 1) -k, --sort-by <int|name> Sort by column (default: 1)
-z, --fuzzy Use fuzzy search [experimental] -z, --fuzzy Use fuzzy search [experimental]
-F, --filter field[!]=reg Filter given field with regex, can be used multiple times -F, --filter <field[!]=reg> Filter given field with regex, can be used multiple times
-T, --transpose-columns string Transpose the speficied columns (separated by ,) -T, --transpose-columns string Transpose the speficied columns (separated by ,)
-R, --regex-transposer /from/to/ Apply /search/replace/ regexp to fields given in -T -R, --regex-transposer </from/to/> Apply /search/replace/ regexp to fields given in -T
-I, --interactive Interactively filter and select rows -I, --interactive Interactively filter and select rows
Output Flags (mutually exclusive): Output Flags (mutually exclusive):
-X, --extended Enable extended output -X, --extended Enable extended output
-M, --markdown Enable markdown table output -M, --markdown Enable markdown table output
-O, --orgtbl Enable org-mode table output -O, --orgtbl Enable org-mode table output
-S, --shell Enable shell evaluable output -S, --shell Enable shell evaluable output
-Y, --yaml Enable yaml output -Y, --yaml Enable yaml output
-C, --csv Enable CSV output -C, --csv Enable CSV output
-A, --ascii Default output mode, ascii tabular -A, --ascii Default output mode, ascii tabular
-L, --hightlight-lines Use alternating background colors for tables -L, --hightlight-lines Use alternating background colors for tables
-y, --yank-columns Yank specified columns (separated by ,) to clipboard, -y, --yank-columns Yank specified columns (separated by ,) to clipboard,
space separated space separated
--ofs <char> Output field separator, used by -A and -C.
Sort Mode Flags (mutually exclusive): Sort Mode Flags (mutually exclusive):
-a, --sort-age sort according to age (duration) string -a, --sort-age sort according to age (duration) string
-D, --sort-desc Sort in descending order (default: ascending) -D, --sort-desc Sort in descending order (default: ascending)
-i, --sort-numeric sort according to string numerical value -i, --sort-numeric sort according to string numerical value
-t, --sort-time sort according to time string -t, --sort-time sort according to time string
Other Flags: Other Flags:
--completion <shell> Generate the autocompletion script for <shell> -r --read-file <file> Use <file> as input instead of STDIN
-f, --config <file> Configuration file (default: ~/.config/tablizer/config) --completion <shell> Generate the autocompletion script for <shell>
-d, --debug Enable debugging -f, --config <file> Configuration file (default: ~/.config/tablizer/config)
-h, --help help for tablizer -d, --debug Enable debugging
-m, --man Display manual page -h, --help help for tablizer
-V, --version Print program version -m, --man Display manual page
-V, --version Print program version
``` ```
Let's take this output: Let's take this output:
@@ -71,13 +79,13 @@ to do this with tablizer:
``` ```
% kubectl get pods | tablizer % kubectl get pods | tablizer
NAME(1) READY(2) STATUS(3) RESTARTS(4) AGE(5) NAME READY STATUS RESTARTS AGE
repldepl-7bcd8d5b64-7zq4l 1/1 Running 1 (69m ago) 5h26m repldepl-7bcd8d5b64-7zq4l 1/1 Running 1 (69m ago) 5h26m
repldepl-7bcd8d5b64-m48n8 1/1 Running 1 (69m ago) 5h26m repldepl-7bcd8d5b64-m48n8 1/1 Running 1 (69m ago) 5h26m
repldepl-7bcd8d5b64-q2bf4 1/1 Running 1 (69m ago) 5h26m repldepl-7bcd8d5b64-q2bf4 1/1 Running 1 (69m ago) 5h26m
% kubectl get pods | tablizer -c 1,3 % kubectl get pods | tablizer -c 1,3
NAME(1) STATUS(3) NAME STATUS
repldepl-7bcd8d5b64-7zq4l Running repldepl-7bcd8d5b64-7zq4l Running
repldepl-7bcd8d5b64-m48n8 Running repldepl-7bcd8d5b64-m48n8 Running
repldepl-7bcd8d5b64-q2bf4 Running repldepl-7bcd8d5b64-q2bf4 Running
@@ -115,14 +123,14 @@ You can also specify a regex pattern to reduce the output:
``` ```
% kubectl get pods | tablizer q2bf4 % kubectl get pods | tablizer q2bf4
NAME(1) READY(2) STATUS(3) RESTARTS(4) AGE(5) NAME READY STATUS RESTARTS AGE
repldepl-7bcd8d5b64-q2bf4 1/1 Running 1 (69m ago) 5h26m repldepl-7bcd8d5b64-q2bf4 1/1 Running 1 (69m ago) 5h26m
``` ```
Sometimes a filter regex is to broad and you wish to filter only on a Sometimes a filter regex is to broad and you wish to filter only on a
particular column. This is possible using `-F`: particular column. This is possible using `-F`:
``` ```
% kubectl get pods | tablizer -n -Fname=2 % kubectl get pods | tablizer -Fname=2
NAME READY STATUS RESTARTS AGE NAME READY STATUS RESTARTS AGE
repldepl-7bcd8d5b64-q2bf4 1/1 Running 1 (69m ago) 5h26m repldepl-7bcd8d5b64-q2bf4 1/1 Running 1 (69m ago) 5h26m
``` ```
@@ -136,7 +144,7 @@ You can also use it to modify certain cells using regular expression
matching. For example: matching. For example:
```shell ```shell
kubectl get pods | tablizer -n -T4 -R '/ /-/' kubectl get pods | tablizer -T4 -R '/ /-/'
NAME READY STATUS RESTARTS AGE NAME READY STATUS RESTARTS AGE
repldepl-7bcd8d5b64-7zq4l 1/1 Running 1-(69m-ago) 5h26m repldepl-7bcd8d5b64-7zq4l 1/1 Running 1-(69m-ago) 5h26m
repldepl-7bcd8d5b64-m48n8 1/1 Running 1-(69m-ago) 5h26m repldepl-7bcd8d5b64-m48n8 1/1 Running 1-(69m-ago) 5h26m
@@ -147,11 +155,12 @@ Here, we modified the 4th column (`-T4`) by replacing every space with
a dash. If you need to work with `/` characters, you can also use any a dash. If you need to work with `/` characters, you can also use any
other separator, for instance: `-R '| |-|'`. other separator, for instance: `-R '| |-|'`.
There's also an interactive mode, invoked with the option B<-I>, where
you can interactively filter and select rows:
<img width="937" height="293" alt="interactive" src="https://github.com/user-attachments/assets/0d4d65e2-d156-43ed-8021-39047c7939ed" />
## Demo
[![asciicast](demo/tablizer-demo.gif)](https://asciinema.org/a/9FKc3HPnlg8D2X8otheleEa9t)
## Installation ## Installation

View File

@@ -28,7 +28,7 @@ import (
) )
const DefaultSeparator string = `(\s\s+|\t)` const DefaultSeparator string = `(\s\s+|\t)`
const Version string = "v1.5.2" const Version string = "v1.5.5"
const MAXPARTS = 2 const MAXPARTS = 2
var DefaultConfigfile = os.Getenv("HOME") + "/.config/tablizer/config" var DefaultConfigfile = os.Getenv("HOME") + "/.config/tablizer/config"
@@ -112,6 +112,8 @@ type Config struct {
// -r <file> // -r <file>
InputFile string InputFile string
OFS string
} }
// maps outputmode short flags to output mode, ie. -O => -o orgtbl // maps outputmode short flags to output mode, ie. -O => -o orgtbl

View File

@@ -132,6 +132,8 @@ func Execute() {
"Transpose the speficied columns (separated by ,)") "Transpose the speficied columns (separated by ,)")
rootCmd.PersistentFlags().BoolVarP(&conf.Interactive, "interactive", "I", false, rootCmd.PersistentFlags().BoolVarP(&conf.Interactive, "interactive", "I", false,
"interactive mode (experimental)") "interactive mode (experimental)")
rootCmd.PersistentFlags().StringVarP(&conf.OFS, "ofs", "", "",
"Output field separator (' ' for ascii table, ',' for CSV)")
// sort options // sort options
rootCmd.PersistentFlags().StringVarP(&conf.SortByColumn, "sort-by", "k", "", rootCmd.PersistentFlags().StringVarP(&conf.SortByColumn, "sort-by", "k", "",

View File

@@ -6,47 +6,49 @@ NAME
SYNOPSIS SYNOPSIS
Usage: Usage:
tablizer [regex,...] [file, ...] [flags] tablizer [regex,...] [-r file] [flags]
Operational Flags: Operational Flags:
-c, --columns string Only show the speficied columns (separated by ,) -c, --columns string Only show the speficied columns (separated by ,)
-v, --invert-match select non-matching rows -v, --invert-match select non-matching rows
-n, --numbering Enable header numbering -n, --numbering Enable header numbering
-N, --no-color Disable pattern highlighting -N, --no-color Disable pattern highlighting
-H, --no-headers Disable headers display -H, --no-headers Disable headers display
-s, --separator string Custom field separator -s, --separator <string> Custom field separator
-k, --sort-by int|name Sort by column (default: 1) -k, --sort-by <int|name> Sort by column (default: 1)
-z, --fuzzy Use fuzzy search [experimental] -z, --fuzzy Use fuzzy search [experimental]
-F, --filter field[!]=reg Filter given field with regex, can be used multiple times -F, --filter <field[!]=reg> Filter given field with regex, can be used multiple times
-T, --transpose-columns string Transpose the speficied columns (separated by ,) -T, --transpose-columns string Transpose the speficied columns (separated by ,)
-R, --regex-transposer /from/to/ Apply /search/replace/ regexp to fields given in -T -R, --regex-transposer </from/to/> Apply /search/replace/ regexp to fields given in -T
-I, --interactive Interactively filter and select rows -I, --interactive Interactively filter and select rows
Output Flags (mutually exclusive): Output Flags (mutually exclusive):
-X, --extended Enable extended output -X, --extended Enable extended output
-M, --markdown Enable markdown table output -M, --markdown Enable markdown table output
-O, --orgtbl Enable org-mode table output -O, --orgtbl Enable org-mode table output
-S, --shell Enable shell evaluable output -S, --shell Enable shell evaluable output
-Y, --yaml Enable yaml output -Y, --yaml Enable yaml output
-C, --csv Enable CSV output -C, --csv Enable CSV output
-A, --ascii Default output mode, ascii tabular -A, --ascii Default output mode, ascii tabular
-L, --hightlight-lines Use alternating background colors for tables -L, --hightlight-lines Use alternating background colors for tables
-y, --yank-columns Yank specified columns (separated by ,) to clipboard, -y, --yank-columns Yank specified columns (separated by ,) to clipboard,
space separated space separated
--ofs <char> Output field separator, used by -A and -C.
Sort Mode Flags (mutually exclusive): Sort Mode Flags (mutually exclusive):
-a, --sort-age sort according to age (duration) string -a, --sort-age sort according to age (duration) string
-D, --sort-desc Sort in descending order (default: ascending) -D, --sort-desc Sort in descending order (default: ascending)
-i, --sort-numeric sort according to string numerical value -i, --sort-numeric sort according to string numerical value
-t, --sort-time sort according to time string -t, --sort-time sort according to time string
Other Flags: Other Flags:
--completion <shell> Generate the autocompletion script for <shell> -r --read-file <file> Use <file> as input instead of STDIN
-f, --config <file> Configuration file (default: ~/.config/tablizer/config) --completion <shell> Generate the autocompletion script for <shell>
-d, --debug Enable debugging -f, --config <file> Configuration file (default: ~/.config/tablizer/config)
-h, --help help for tablizer -d, --debug Enable debugging
-m, --man Display manual page -h, --help help for tablizer
-V, --version Print program version -m, --man Display manual page
-V, --version Print program version
DESCRIPTION DESCRIPTION
Many programs generate tabular output. But sometimes you need to Many programs generate tabular output. But sometimes you need to
@@ -74,16 +76,16 @@ DESCRIPTION
kubectl get pods | tablizer kubectl get pods | tablizer
# read a file # read a file
tablizer filename tablizer -r filename
# search for pattern in a file (works like grep) # search for pattern in a file (works like grep)
tablizer regex filename tablizer regex -r filename
# search for pattern in STDIN # search for pattern in STDIN
kubectl get pods | tablizer regex kubectl get pods | tablizer regex
The output looks like the original one but every header field will have The output looks like the original one. You can add the option -n, then
a numer associated with it, e.g.: every header field will have a numer associated with it, e.g.:
NAME(1) READY(2) STATUS(3) RESTARTS(4) AGE(5) NAME(1) READY(2) STATUS(3) RESTARTS(4) AGE(5)
@@ -95,7 +97,13 @@ DESCRIPTION
You can specify the numbers in any order but output will always follow You can specify the numbers in any order but output will always follow
the original order. the original order.
The numbering can be suppressed by using the -n option. However, you may also just use the header names instead of numbers, eg:
kubectl get pods | tablizer -cname,status
You can also use regular expressions with -c, eg:
kubectl get pods | tablizer -c '[ae]'
By default tablizer shows a header containing the names of each column. By default tablizer shows a header containing the names of each column.
This can be disabled using the -H option. Be aware that this only This can be disabled using the -H option. Be aware that this only
@@ -441,47 +449,49 @@ AUTHORS
var usage = ` var usage = `
Usage: Usage:
tablizer [regex,...] [file, ...] [flags] tablizer [regex,...] [-r file] [flags]
Operational Flags: Operational Flags:
-c, --columns string Only show the speficied columns (separated by ,) -c, --columns string Only show the speficied columns (separated by ,)
-v, --invert-match select non-matching rows -v, --invert-match select non-matching rows
-n, --numbering Enable header numbering -n, --numbering Enable header numbering
-N, --no-color Disable pattern highlighting -N, --no-color Disable pattern highlighting
-H, --no-headers Disable headers display -H, --no-headers Disable headers display
-s, --separator string Custom field separator -s, --separator <string> Custom field separator
-k, --sort-by int|name Sort by column (default: 1) -k, --sort-by <int|name> Sort by column (default: 1)
-z, --fuzzy Use fuzzy search [experimental] -z, --fuzzy Use fuzzy search [experimental]
-F, --filter field[!]=reg Filter given field with regex, can be used multiple times -F, --filter <field[!]=reg> Filter given field with regex, can be used multiple times
-T, --transpose-columns string Transpose the speficied columns (separated by ,) -T, --transpose-columns string Transpose the speficied columns (separated by ,)
-R, --regex-transposer /from/to/ Apply /search/replace/ regexp to fields given in -T -R, --regex-transposer </from/to/> Apply /search/replace/ regexp to fields given in -T
-I, --interactive Interactively filter and select rows -I, --interactive Interactively filter and select rows
Output Flags (mutually exclusive): Output Flags (mutually exclusive):
-X, --extended Enable extended output -X, --extended Enable extended output
-M, --markdown Enable markdown table output -M, --markdown Enable markdown table output
-O, --orgtbl Enable org-mode table output -O, --orgtbl Enable org-mode table output
-S, --shell Enable shell evaluable output -S, --shell Enable shell evaluable output
-Y, --yaml Enable yaml output -Y, --yaml Enable yaml output
-C, --csv Enable CSV output -C, --csv Enable CSV output
-A, --ascii Default output mode, ascii tabular -A, --ascii Default output mode, ascii tabular
-L, --hightlight-lines Use alternating background colors for tables -L, --hightlight-lines Use alternating background colors for tables
-y, --yank-columns Yank specified columns (separated by ,) to clipboard, -y, --yank-columns Yank specified columns (separated by ,) to clipboard,
space separated space separated
--ofs <char> Output field separator, used by -A and -C.
Sort Mode Flags (mutually exclusive): Sort Mode Flags (mutually exclusive):
-a, --sort-age sort according to age (duration) string -a, --sort-age sort according to age (duration) string
-D, --sort-desc Sort in descending order (default: ascending) -D, --sort-desc Sort in descending order (default: ascending)
-i, --sort-numeric sort according to string numerical value -i, --sort-numeric sort according to string numerical value
-t, --sort-time sort according to time string -t, --sort-time sort according to time string
Other Flags: Other Flags:
--completion <shell> Generate the autocompletion script for <shell> -r --read-file <file> Use <file> as input instead of STDIN
-f, --config <file> Configuration file (default: ~/.config/tablizer/config) --completion <shell> Generate the autocompletion script for <shell>
-d, --debug Enable debugging -f, --config <file> Configuration file (default: ~/.config/tablizer/config)
-h, --help help for tablizer -d, --debug Enable debugging
-m, --man Display manual page -h, --help help for tablizer
-V, --version Print program version -m, --man Display manual page
-V, --version Print program version
` `

View File

@@ -1,3 +0,0 @@
all:
LC_ALL=en_US.UTF-8 asciinema rec --cols 50 --row 30 -c ./demo.sh --overwrite tmp.cast
agg tmp.cast tmp.gif

View File

@@ -1,31 +0,0 @@
#!/bin/bash
prompt() {
if test -n "$1"; then
echo
echo -n "% $*"
sleep 1
echo
$*
echo
echo -n "% "
else
echo -n "% "
fi
}
PATH=..:$PATH
clear
while IFS=$'\t' read -r flags table msg source _; do
echo "#"
echo "# source tabular data:"
cat $table
echo
echo "#"
echo "# $msg:"
prompt "tablizer $flags $table"
sleep 4
clear
done < <(yq -r tables.yaml \
| yq -r '.tables[] | [.flags, .table, .msg, .source] | @tsv')

View File

@@ -1,4 +0,0 @@
NAME DURATION COUNT WHEN
beta 1d10h5m1s 33 3/1/2014
alpha 4h35m 170 2013-Feb-03
ceta 33d12h 9 06/Jan/2008 15:04:05 -0700

View File

@@ -1,3 +0,0 @@
PID TTY TIME CMD
30912 pts/0 00:00:00 bash
49526 pts/0 00:00:00 ps

View File

@@ -1,54 +0,0 @@
tables:
# OUTPUTS
- flags: -A
table: table.demo1
msg: default output mode
- flags: -O
table: table.demo1
msg: orgmode output mode
- flags: -M
table: table.demo1
msg: markdown output mode
- flags: -S
table: table.demo1
msg: shell output mode
- flags: -X
table: table.demo1
msg: extended output mode
- flags: -Y
table: table.demo1
msg: yaml output mode
- flags: -C
table: table.demo1
msg: CSV output mode
# SORTS
- flags: -A -k 3
table: table.demo1
msg: sort by column 3
- flags: -A -k 4 -t
table: table.demo1
msg: sort by column 4 and sort type time
- flags: -A -k 2 -a
table: table.demo1
msg: sort by column 2 and sort type duration
# REDUCE
- flags: -A -c 1,3
table: table.demo1
msg: only display column 1 and 3
- flags: -A -c AM,RA
table: table.demo1
msg: only display columns matching /(RA|AM)/
- flags: -X -c 1,3
table: table.demo1
msg: only display column 1 and 3 in extended mode
# SEARCH
- flags: /20 -A
table: table.demo1
msg: only show rows matching /20
- flags: /20 -A -v
table: table.demo1
msg: only show rows NOT matching /20

View File

@@ -1,119 +0,0 @@
{"version": 2, "width": 80, "height": 25, "timestamp": 1666890777, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}}
[0.004618, "o", "\u001b[H\u001b[2J\u001b[3J"]
[0.010297, "o", "#\r\n# source tabular data:\r\n"]
[0.010898, "o", "NAME DURATION COUNT WHEN\r\nbeta 1d10h5m1s 33 3/1/2014\r\nalpha 4h35m 170 2013-Feb-03\r\nceta 33d12h 9 06/Jan/2008 15:04:05 -0700\r\n"]
[0.011125, "o", "\r\n#\r\n"]
[0.011177, "o", "# default output mode:\r\n"]
[0.011219, "o", "\r\n% tablizer -A table.demo1"]
[1.011851, "o", "\r\n"]
[1.013635, "o", "NAME(1)\tDURATION(2)\tCOUNT(3)\tWHEN(4) \r\nbeta \t1d10h5m1s \t33 \t3/1/2014 \t\r\nalpha \t4h35m \t170 \t2013-Feb-03 \t\r\nceta \t33d12h \t9 \t06/Jan/2008 15:04:05 -0700\t\r\n"]
[1.014021, "o", "\r\n% "]
[5.015241, "o", "\u001b[H\u001b[2J\u001b[3J"]
[5.015339, "o", "#\r\n# source tabular data:\r\n"]
[5.015688, "o", "NAME DURATION COUNT WHEN\r\nbeta 1d10h5m1s 33 3/1/2014\r\nalpha 4h35m 170 2013-Feb-03\r\nceta 33d12h 9 06/Jan/2008 15:04:05 -0700\r\n"]
[5.015776, "o", "\r\n#\r\n# orgmode output mode:\r\n\r\n% tablizer -O table.demo1"]
[6.016322, "o", "\r\n"]
[6.01823, "o", "+---------+-------------+----------+----------------------------+\r\n| NAME(1) | DURATION(2) | COUNT(3) | WHEN(4) |\r\n+---------+-------------+----------+----------------------------+\r\n| beta | 1d10h5m1s | 33 | 3/1/2014 |\r\n| alpha | 4h35m | 170 | 2013-Feb-03 |\r\n| ceta | 33d12h | 9 | 06/Jan/2008 15:04:05 -0700 |\r\n+---------+-------------+----------+----------------------------+\r\n"]
[6.018497, "o", "\r\n% "]
[10.020014, "o", "\u001b[H\u001b[2J\u001b[3J"]
[10.020112, "o", "#\r\n# source tabular data:\r\n"]
[10.020573, "o", "NAME DURATION COUNT WHEN\r\nbeta 1d10h5m1s 33 3/1/2014\r\nalpha 4h35m 170 2013-Feb-03\r\nceta 33d12h 9 06/Jan/2008 15:04:05 -0700\r\n"]
[10.020643, "o", "\r\n#\r\n"]
[10.02068, "o", "# markdown output mode:\r\n\r\n% tablizer -M table.demo1"]
[11.021559, "o", "\r\n"]
[11.023551, "o", "| NAME(1) | DURATION(2) | COUNT(3) | WHEN(4) |\r\n|---------|-------------|----------|----------------------------|\r\n| beta | 1d10h5m1s | 33 | 3/1/2014 |\r\n| alpha | 4h35m | 170 | 2013-Feb-03 |\r\n| ceta | 33d12h | 9 | 06/Jan/2008 15:04:05 -0700 |\r\n"]
[11.023838, "o", "\r\n% "]
[15.025244, "o", "\u001b[H\u001b[2J\u001b[3J"]
[15.025345, "o", "#\r\n# source tabular data:\r\n"]
[15.025829, "o", "NAME DURATION COUNT WHEN\r\nbeta 1d10h5m1s 33 3/1/2014\r\nalpha 4h35m 170 2013-Feb-03\r\nceta 33d12h 9 06/Jan/2008 15:04:05 -0700\r\n"]
[15.025915, "o", "\r\n#\r\n# shell output mode:\r\n"]
[15.025931, "o", "\r\n"]
[15.025948, "o", "% tablizer -S table.demo1"]
[16.026714, "o", "\r\n"]
[16.028606, "o", "NAME(1)=\"beta\" DURATION(2)=\"1d10h5m1s\" COUNT(3)=\"33\" WHEN(4)=\"3/1/2014\"\r\nNAME(1)=\"alpha\" DURATION(2)=\"4h35m\" COUNT(3)=\"170\" WHEN(4)=\"2013-Feb-03\"\r\nNAME(1)=\"ceta\" DURATION(2)=\"33d12h\" COUNT(3)=\"9\" WHEN(4)=\"06/Jan/2008 15:04:05 -0700\"\r\n"]
[16.029144, "o", "\r\n% "]
[20.030593, "o", "\u001b[H\u001b[2J\u001b[3J"]
[20.030706, "o", "#\r\n# source tabular data:\r\n"]
[20.03121, "o", "NAME DURATION COUNT WHEN\r\nbeta 1d10h5m1s 33 3/1/2014\r\nalpha 4h35m 170 2013-Feb-03\r\nceta 33d12h 9 06/Jan/2008 15:04:05 -0700\r\n"]
[20.031277, "o", "\r\n#\r\n# extended output mode:\r\n"]
[20.031327, "o", "\r\n% tablizer -X table.demo1"]
[21.032053, "o", "\r\n"]
[21.033787, "o", " NAME(1): beta\r\nDURATION(2): 1d10h5m1s\r\n COUNT(3): 33\r\n WHEN(4): 3/1/2014\r\n\r\n NAME(1): alpha\r\nDURATION(2): 4h35m\r\n COUNT(3): 170\r\n WHEN(4): 2013-Feb-03\r\n\r\n NAME(1): ceta\r\nDURATION(2): 33d12h\r\n COUNT(3): 9\r\n WHEN(4): 06/Jan/2008 15:04:05 -0700\r\n\r\n"]
[21.034132, "o", "\r\n% "]
[25.035531, "o", "\u001b[H\u001b[2J\u001b[3J"]
[25.035585, "o", "#\r\n"]
[25.035681, "o", "# source tabular data:\r\n"]
[25.036179, "o", "NAME DURATION COUNT WHEN\r\nbeta 1d10h5m1s 33 3/1/2014\r\nalpha 4h35m 170 2013-Feb-03\r\nceta 33d12h 9 06/Jan/2008 15:04:05 -0700\r\n"]
[25.036232, "o", "\r\n#\r\n"]
[25.036274, "o", "# yaml output mode:\r\n\r\n% tablizer -Y table.demo1"]
[26.036928, "o", "\r\n"]
[26.038674, "o", "entries:\r\n - count: 33\r\n duration: \"1d10h5m1s\"\r\n name: \"beta\"\r\n when: \"3/1/2014\"\r\n - count: 170\r\n duration: \"4h35m\"\r\n name: \"alpha\"\r\n when: \"2013-Feb-03\"\r\n - count: 9\r\n duration: \"33d12h\"\r\n name: \"ceta\"\r\n when: \"06/Jan/2008 15:04:05 -0700\"\r\n"]
[26.038975, "o", "\r\n% "]
[30.040539, "o", "\u001b[H\u001b[2J\u001b[3J"]
[30.040659, "o", "#\r\n# source tabular data:\r\n"]
[30.041167, "o", "NAME DURATION COUNT WHEN\r\nbeta 1d10h5m1s 33 3/1/2014\r\nalpha 4h35m 170 2013-Feb-03\r\nceta 33d12h 9 06/Jan/2008 15:04:05 -0700\r\n"]
[30.041246, "o", "\r\n#\r\n# CSV output mode:\r\n\r\n% tablizer -C table.demo1"]
[31.042088, "o", "\r\n"]
[31.043721, "o", "NAME,DURATION,COUNT,WHEN\r\nbeta,1d10h5m1s,33,3/1/2014\r\nalpha,4h35m,170,2013-Feb-03\r\nceta,33d12h,9,06/Jan/2008 15:04:05 -0700\r\n"]
[31.043997, "o", "\r\n% "]
[35.045523, "o", "\u001b[H\u001b[2J\u001b[3J"]
[35.04563, "o", "#\r\n# source tabular data:\r\n"]
[35.046209, "o", "NAME DURATION COUNT WHEN\r\nbeta 1d10h5m1s 33 3/1/2014\r\nalpha 4h35m 170 2013-Feb-03\r\nceta 33d12h 9 06/Jan/2008 15:04:05 -0700\r\n"]
[35.046275, "o", "\r\n#\r\n# sort by column 3:\r\n\r\n% tablizer -A -k 3 table.demo1"]
[36.047083, "o", "\r\n"]
[36.048793, "o", "NAME(1)\tDURATION(2)\tCOUNT(3)\tWHEN(4) \r\nalpha \t4h35m \t170 \t2013-Feb-03 \t\r\nbeta \t1d10h5m1s \t33 \t3/1/2014 \t\r\nceta \t33d12h \t9 \t06/Jan/2008 15:04:05 -0700\t\r\n"]
[36.049077, "o", "\r\n% "]
[40.050739, "o", "\u001b[H\u001b[2J\u001b[3J"]
[40.050925, "o", "#\r\n# source tabular data:\r\n"]
[40.051481, "o", "NAME DURATION COUNT WHEN\r\nbeta 1d10h5m1s 33 3/1/2014\r\nalpha 4h35m 170 2013-Feb-03\r\nceta 33d12h 9 06/Jan/2008 15:04:05 -0700\r\n"]
[40.051671, "o", "\r\n#\r\n# sort by column 4 and sort type time:\r\n\r\n% tablizer -A -k 4 -t table.demo1"]
[41.052486, "o", "\r\n"]
[41.05454, "o", "NAME(1)\tDURATION(2)\tCOUNT(3)\tWHEN(4) \r\nceta \t33d12h \t9 \t06/Jan/2008 15:04:05 -0700\t\r\nalpha \t4h35m \t170 \t2013-Feb-03 \t\r\nbeta \t1d10h5m1s \t33 \t3/1/2014 \t\r\n"]
[41.054864, "o", "\r\n% "]
[45.056297, "o", "\u001b[H\u001b[2J\u001b[3J"]
[45.056405, "o", "#\r\n# source tabular data:\r\n"]
[45.056895, "o", "NAME DURATION COUNT WHEN\r\nbeta 1d10h5m1s 33 3/1/2014\r\nalpha 4h35m 170 2013-Feb-03\r\nceta 33d12h 9 06/Jan/2008 15:04:05 -0700\r\n"]
[45.056978, "o", "\r\n#\r\n"]
[45.057023, "o", "# sort by column 2 and sort type duration:\r\n"]
[45.057073, "o", "\r\n% tablizer -A -k 2 -a table.demo1"]
[46.057895, "o", "\r\n"]
[46.059684, "o", "NAME(1)\tDURATION(2)\tCOUNT(3)\tWHEN(4) \r\nalpha \t4h35m \t170 \t2013-Feb-03 \t\r\nbeta \t1d10h5m1s \t33 \t3/1/2014 \t\r\nceta \t33d12h \t9 \t06/Jan/2008 15:04:05 -0700\t\r\n"]
[46.059988, "o", "\r\n% "]
[50.061514, "o", "\u001b[H\u001b[2J\u001b[3J"]
[50.061622, "o", "#\r\n# source tabular data:\r\n"]
[50.062091, "o", "NAME DURATION COUNT WHEN\r\nbeta 1d10h5m1s 33 3/1/2014\r\nalpha 4h35m 170 2013-Feb-03\r\nceta 33d12h 9 06/Jan/2008 15:04:05 -0700\r\n"]
[50.062188, "o", "\r\n#\r\n# only display column 1 and 3:\r\n\r\n% tablizer -A -c 1,3 table.demo1"]
[51.062985, "o", "\r\n"]
[51.066293, "o", "NAME(1)\tCOUNT(3) \r\nbeta \t33 \t\r\nalpha \t170 \t\r\nceta \t9 \t\r\n"]
[51.066843, "o", "\r\n% "]
[55.070781, "o", "\u001b[H\u001b[2J\u001b[3J"]
[55.071327, "o", "#\r\n# source tabular data:\r\n"]
[55.073499, "o", "NAME DURATION COUNT WHEN\r\nbeta 1d10h5m1s 33 3/1/2014\r\nalpha 4h35m 170 2013-Feb-03\r\nceta 33d12h 9 06/Jan/2008 15:04:05 -0700\r\n"]
[55.073822, "o", "\r\n#\r\n# only display columns matching /(RA|AM)/:\r\n"]
[55.074188, "o", "\r\n% tablizer -A -c AM,RA table.demo1"]
[56.07636, "o", "\r\n"]
[56.078603, "o", "NAME(1)\tDURATION(2) \r\nbeta \t1d10h5m1s \t\r\nalpha \t4h35m \t\r\nceta \t33d12h \t\r\n"]
[56.078957, "o", "\r\n% "]
[60.080574, "o", "\u001b[H\u001b[2J\u001b[3J"]
[60.080734, "o", "#\r\n# source tabular data:\r\n"]
[60.081286, "o", "NAME DURATION COUNT WHEN\r\nbeta 1d10h5m1s 33 3/1/2014\r\nalpha 4h35m 170 2013-Feb-03\r\nceta 33d12h 9 06/Jan/2008 15:04:05 -0700\r\n"]
[60.081418, "o", "\r\n#\r\n# only display column 1 and 3 in extended mode:\r\n\r\n% tablizer -X -c 1,3 table.demo1"]
[61.082844, "o", "\r\n"]
[61.089822, "o", " NAME(1): beta\r\nCOUNT(3): 33\r\n\r\n NAME(1): alpha\r\nCOUNT(3): 170\r\n\r\n NAME(1): ceta\r\nCOUNT(3): 9\r\n\r\n"]
[61.090969, "o", "\r\n% "]
[65.096092, "o", "\u001b[H\u001b[2J\u001b[3J"]
[65.096571, "o", "#\r\n# source tabular data:\r\n"]
[65.098736, "o", "NAME DURATION COUNT WHEN\r\nbeta 1d10h5m1s 33 3/1/2014\r\nalpha 4h35m 170 2013-Feb-03\r\nceta 33d12h 9 06/Jan/2008 15:04:05 -0700\r\n"]
[65.099085, "o", "\r\n#\r\n# only show rows matching /20:\r\n"]
[65.099283, "o", "\r\n% tablizer /20 -A table.demo1"]
[66.101537, "o", "\r\n"]
[66.109112, "o", "NAME(1)\tDURATION(2)\tCOUNT(3)\tWHEN(4) \r\nbeta \t1d10h5m1s \t33 \t3/1\u001b[102;30m/20\u001b[0m14 \t\r\nceta \t33d12h \t9 \t06/Jan\u001b[102;30m/20\u001b[0m08 15:04:05 -0700\t\r\n"]
[66.109405, "o", "\r\n% "]
[70.11076, "o", "\u001b[H\u001b[2J\u001b[3J"]
[70.110873, "o", "#\r\n# source tabular data:\r\n"]
[70.111365, "o", "NAME DURATION COUNT WHEN\r\nbeta 1d10h5m1s 33 3/1/2014\r\nalpha 4h35m 170 2013-Feb-03\r\nceta 33d12h 9 06/Jan/2008 15:04:05 -0700\r\n"]
[70.111469, "o", "\r\n#\r\n# only show rows NOT matching /20:\r\n\r\n% tablizer /20 -A -v table.demo1"]
[71.112738, "o", "\r\n"]
[71.120032, "o", "NAME(1)\tDURATION(2)\tCOUNT(3)\tWHEN(4) \r\nalpha \t4h35m \t170 \t2013-Feb-03\t\r\n"]
[71.121127, "o", "\r\n% "]
[75.126199, "o", "\u001b[H\u001b[2J\u001b[3J"]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 KiB

View File

@@ -62,7 +62,7 @@ func printData(writer io.Writer, conf cfg.Config, data *Tabdata) {
case cfg.Yaml: case cfg.Yaml:
printYamlData(writer, data) printYamlData(writer, data)
case cfg.CSV: case cfg.CSV:
printCSVData(writer, data) printCSVData(writer, conf, data)
default: default:
printASCIIData(writer, conf, data) printASCIIData(writer, conf, data)
} }
@@ -194,6 +194,11 @@ func printMarkdownData(writer io.Writer, conf cfg.Config, data *Tabdata) {
Simple ASCII table without any borders etc, just like the input we expect Simple ASCII table without any borders etc, just like the input we expect
*/ */
func printASCIIData(writer io.Writer, conf cfg.Config, data *Tabdata) { func printASCIIData(writer io.Writer, conf cfg.Config, data *Tabdata) {
OFS := " "
if conf.OFS != "" {
OFS = conf.OFS
}
tableString := &strings.Builder{} tableString := &strings.Builder{}
styleTSV := tw.NewSymbolCustom("space").WithColumn("\t") styleTSV := tw.NewSymbolCustom("space").WithColumn("\t")
@@ -204,8 +209,8 @@ func printASCIIData(writer io.Writer, conf cfg.Config, data *Tabdata) {
Borders: tw.BorderNone, Borders: tw.BorderNone,
Symbols: styleTSV, Symbols: styleTSV,
Settings: tw.Settings{ Settings: tw.Settings{
Separators: tw.Separators{BetweenRows: tw.Off, BetweenColumns: tw.On}, Separators: tw.SeparatorsNone,
Lines: tw.Lines{ShowFooterLine: tw.Off, ShowHeaderLine: tw.Off}, Lines: tw.LinesNone,
}, },
})), })),
tablewriter.WithConfig(tablewriter.Config{ tablewriter.WithConfig(tablewriter.Config{
@@ -213,23 +218,18 @@ func printASCIIData(writer io.Writer, conf cfg.Config, data *Tabdata) {
Formatting: tw.CellFormatting{ Formatting: tw.CellFormatting{
AutoFormat: tw.Off, AutoFormat: tw.Off,
}, },
Padding: tw.CellPadding{ Padding: tw.CellPadding{Global: tw.Padding{Left: "", Right: OFS}},
Global: tw.Padding{Left: "", Right: ""},
},
}, },
Row: tw.CellConfig{ Row: tw.CellConfig{
Formatting: tw.CellFormatting{ Formatting: tw.CellFormatting{
AutoWrap: tw.WrapNone, AutoWrap: tw.WrapNone,
Alignment: tw.AlignLeft, Alignment: tw.AlignLeft,
}, },
Padding: tw.CellPadding{ Padding: tw.CellPadding{Global: tw.Padding{Right: OFS}},
Global: tw.Padding{Left: "", Right: ""},
},
}, },
Debug: true, Debug: true,
}), }),
tablewriter.WithPadding(tw.PaddingNone),
) )
if !conf.NoHeaders { if !conf.NoHeaders {
@@ -328,8 +328,14 @@ func printYamlData(writer io.Writer, data *Tabdata) {
output(writer, string(yamlstr)) output(writer, string(yamlstr))
} }
func printCSVData(writer io.Writer, data *Tabdata) { func printCSVData(writer io.Writer, conf cfg.Config, data *Tabdata) {
OFS := ","
if conf.OFS != "" {
OFS = conf.OFS
}
csvout := csv.NewWriter(writer) csvout := csv.NewWriter(writer)
csvout.Comma = []rune(OFS)[0]
if err := csvout.Write(data.headers); err != nil { if err := csvout.Write(data.headers); err != nil {
log.Fatalln("error writing record to csv:", err) log.Fatalln("error writing record to csv:", err)

View File

@@ -77,10 +77,10 @@ var tests = []struct {
numberize: true, numberize: true,
name: "default", name: "default",
expect: ` expect: `
NAME(1) DURATION(2) COUNT(3) WHEN(4) NAME(1) DURATION(2) COUNT(3) WHEN(4)
beta 1d10h5m1s 33 3/1/2014 beta 1d10h5m1s 33 3/1/2014
alpha 4h35m 170 2013-Feb-03 alpha 4h35m 170 2013-Feb-03
ceta 33d12h 9 06/Jan/2008 15:04:05 -0700`, ceta 33d12h 9 06/Jan/2008 15:04:05 -0700`,
}, },
{ {
mode: cfg.CSV, mode: cfg.CSV,
@@ -173,10 +173,10 @@ DURATION(2): 33d12h
numberize: true, numberize: true,
desc: false, desc: false,
expect: ` expect: `
NAME(1) DURATION(2) COUNT(3) WHEN(4) NAME(1) DURATION(2) COUNT(3) WHEN(4)
ceta 33d12h 9 06/Jan/2008 15:04:05 -0700 ceta 33d12h 9 06/Jan/2008 15:04:05 -0700
beta 1d10h5m1s 33 3/1/2014 beta 1d10h5m1s 33 3/1/2014
alpha 4h35m 170 2013-Feb-03`, alpha 4h35m 170 2013-Feb-03`,
}, },
{ {
name: "sortbycolumn4", name: "sortbycolumn4",
@@ -185,10 +185,10 @@ alpha 4h35m 170 2013-Feb-03`,
desc: false, desc: false,
numberize: true, numberize: true,
expect: ` expect: `
NAME(1) DURATION(2) COUNT(3) WHEN(4) NAME(1) DURATION(2) COUNT(3) WHEN(4)
ceta 33d12h 9 06/Jan/2008 15:04:05 -0700 ceta 33d12h 9 06/Jan/2008 15:04:05 -0700
alpha 4h35m 170 2013-Feb-03 alpha 4h35m 170 2013-Feb-03
beta 1d10h5m1s 33 3/1/2014`, beta 1d10h5m1s 33 3/1/2014`,
}, },
{ {
name: "sortbycolumn2", name: "sortbycolumn2",
@@ -197,10 +197,10 @@ beta 1d10h5m1s 33 3/1/2014`,
numberize: true, numberize: true,
desc: false, desc: false,
expect: ` expect: `
NAME(1) DURATION(2) COUNT(3) WHEN(4) NAME(1) DURATION(2) COUNT(3) WHEN(4)
alpha 4h35m 170 2013-Feb-03 alpha 4h35m 170 2013-Feb-03
beta 1d10h5m1s 33 3/1/2014 beta 1d10h5m1s 33 3/1/2014
ceta 33d12h 9 06/Jan/2008 15:04:05 -0700`, ceta 33d12h 9 06/Jan/2008 15:04:05 -0700`,
}, },
// ----------------------- UseColumns Tests // ----------------------- UseColumns Tests
@@ -210,13 +210,13 @@ ceta 33d12h 9 06/Jan/2008 15:04:05 -0700`,
numberize: true, numberize: true,
usecolstr: "1,4", usecolstr: "1,4",
expect: ` expect: `
NAME(1) WHEN(4) NAME(1) WHEN(4)
beta 3/1/2014 beta 3/1/2014
alpha 2013-Feb-03 alpha 2013-Feb-03
ceta 06/Jan/2008 15:04:05 -0700`, ceta 06/Jan/2008 15:04:05 -0700`,
}, },
{ {
name: "usecolumns", name: "usecolumns2",
usecol: []int{2}, usecol: []int{2},
numberize: true, numberize: true,
usecolstr: "2", usecolstr: "2",
@@ -227,7 +227,7 @@ DURATION(2)
33d12h`, 33d12h`,
}, },
{ {
name: "usecolumns", name: "usecolumns3",
usecol: []int{3}, usecol: []int{3},
numberize: true, numberize: true,
usecolstr: "3", usecolstr: "3",
@@ -238,16 +238,16 @@ COUNT(3)
9`, 9`,
}, },
{ {
name: "usecolumns", name: "usecolumns4",
column: 0, column: 0,
usecol: []int{1, 3}, usecol: []int{1, 3},
numberize: true, numberize: true,
usecolstr: "1,3", usecolstr: "1,3",
expect: ` expect: `
NAME(1) COUNT(3) NAME(1) COUNT(3)
beta 33 beta 33
alpha 170 alpha 170
ceta 9`, ceta 9`,
}, },
{ {
name: "usecolumns", name: "usecolumns",
@@ -255,10 +255,10 @@ ceta 9`,
numberize: true, numberize: true,
usecolstr: "2,4", usecolstr: "2,4",
expect: ` expect: `
DURATION(2) WHEN(4) DURATION(2) WHEN(4)
1d10h5m1s 3/1/2014 1d10h5m1s 3/1/2014
4h35m 2013-Feb-03 4h35m 2013-Feb-03
33d12h 06/Jan/2008 15:04:05 -0700`, 33d12h 06/Jan/2008 15:04:05 -0700`,
}, },
} }
@@ -280,6 +280,11 @@ func TestPrinter(t *testing.T) {
Numbering: testdata.numberize, Numbering: testdata.numberize,
UseColumns: testdata.usecol, UseColumns: testdata.usecol,
NoColor: true, NoColor: true,
OFS: " ",
}
if conf.OutputMode == cfg.CSV {
conf.OFS = ","
} }
if testdata.column > 0 { if testdata.column > 0 {
@@ -304,7 +309,10 @@ func TestPrinter(t *testing.T) {
if got != exp { if got != exp {
t.Errorf("not rendered correctly:\n+++ got:\n%s\n+++ want:\n%s", t.Errorf("not rendered correctly:\n+++ got:\n%s\n+++ want:\n%s",
got, exp) got, exp,
// strings.ReplaceAll(got, " ", "_"),
// strings.ReplaceAll(exp, " ", "_")
)
} }
}) })
} }

View File

@@ -25,6 +25,7 @@ import (
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss"
"github.com/evertras/bubble-table/table" "github.com/evertras/bubble-table/table"
"github.com/mattn/go-isatty"
"github.com/tlinden/tablizer/cfg" "github.com/tlinden/tablizer/cfg"
) )
@@ -468,7 +469,14 @@ func tableEditor(conf *cfg.Config, data *Tabdata) (*Tabdata, error) {
// see https://github.com/charmbracelet/bubbletea/issues/860 // see https://github.com/charmbracelet/bubbletea/issues/860
// //
// TODO: doesn't work with libgloss v2 anymore! // TODO: doesn't work with libgloss v2 anymore!
lipgloss.SetDefaultRenderer(lipgloss.NewRenderer(os.Stderr))
out := os.Stderr
if isatty.IsTerminal(os.Stdout.Fd()) {
out = os.Stdout
}
lipgloss.SetDefaultRenderer(lipgloss.NewRenderer(out))
ctx := &Context{data: data} ctx := &Context{data: data}
@@ -479,7 +487,7 @@ func tableEditor(conf *cfg.Config, data *Tabdata) (*Tabdata, error) {
// still be used inside pipes. // still be used inside pipes.
program := tea.NewProgram( program := tea.NewProgram(
NewModel(data, ctx), NewModel(data, ctx),
tea.WithOutput(os.Stderr), tea.WithOutput(out),
tea.WithAltScreen()) tea.WithAltScreen())
m, err := program.Run() m, err := program.Run()

View File

@@ -133,7 +133,7 @@
.\" ======================================================================== .\" ========================================================================
.\" .\"
.IX Title "TABLIZER 1" .IX Title "TABLIZER 1"
.TH TABLIZER 1 "2025-08-28" "1" "User Commands" .TH TABLIZER 1 "2025-09-30" "1" "User Commands"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents. .\" way too many mistakes in technical documents.
.if n .ad l .if n .ad l
@@ -144,47 +144,49 @@ tablizer \- Manipulate tabular output of other programs
.IX Header "SYNOPSIS" .IX Header "SYNOPSIS"
.Vb 2 .Vb 2
\& Usage: \& Usage:
\& tablizer [regex,...] [file, ...] [flags] \& tablizer [regex,...] [\-r file] [flags]
\& \&
\& Operational Flags: \& Operational Flags:
\& \-c, \-\-columns string Only show the speficied columns (separated by ,) \& \-c, \-\-columns string Only show the speficied columns (separated by ,)
\& \-v, \-\-invert\-match select non\-matching rows \& \-v, \-\-invert\-match select non\-matching rows
\& \-n, \-\-numbering Enable header numbering \& \-n, \-\-numbering Enable header numbering
\& \-N, \-\-no\-color Disable pattern highlighting \& \-N, \-\-no\-color Disable pattern highlighting
\& \-H, \-\-no\-headers Disable headers display \& \-H, \-\-no\-headers Disable headers display
\& \-s, \-\-separator string Custom field separator \& \-s, \-\-separator <string> Custom field separator
\& \-k, \-\-sort\-by int|name Sort by column (default: 1) \& \-k, \-\-sort\-by <int|name> Sort by column (default: 1)
\& \-z, \-\-fuzzy Use fuzzy search [experimental] \& \-z, \-\-fuzzy Use fuzzy search [experimental]
\& \-F, \-\-filter field[!]=reg Filter given field with regex, can be used multiple times \& \-F, \-\-filter <field[!]=reg> Filter given field with regex, can be used multiple times
\& \-T, \-\-transpose\-columns string Transpose the speficied columns (separated by ,) \& \-T, \-\-transpose\-columns string Transpose the speficied columns (separated by ,)
\& \-R, \-\-regex\-transposer /from/to/ Apply /search/replace/ regexp to fields given in \-T \& \-R, \-\-regex\-transposer </from/to/> Apply /search/replace/ regexp to fields given in \-T
\& \-I, \-\-interactive Interactively filter and select rows \& \-I, \-\-interactive Interactively filter and select rows
\& \&
\& Output Flags (mutually exclusive): \& Output Flags (mutually exclusive):
\& \-X, \-\-extended Enable extended output \& \-X, \-\-extended Enable extended output
\& \-M, \-\-markdown Enable markdown table output \& \-M, \-\-markdown Enable markdown table output
\& \-O, \-\-orgtbl Enable org\-mode table output \& \-O, \-\-orgtbl Enable org\-mode table output
\& \-S, \-\-shell Enable shell evaluable output \& \-S, \-\-shell Enable shell evaluable output
\& \-Y, \-\-yaml Enable yaml output \& \-Y, \-\-yaml Enable yaml output
\& \-C, \-\-csv Enable CSV output \& \-C, \-\-csv Enable CSV output
\& \-A, \-\-ascii Default output mode, ascii tabular \& \-A, \-\-ascii Default output mode, ascii tabular
\& \-L, \-\-hightlight\-lines Use alternating background colors for tables \& \-L, \-\-hightlight\-lines Use alternating background colors for tables
\& \-y, \-\-yank\-columns Yank specified columns (separated by ,) to clipboard, \& \-y, \-\-yank\-columns Yank specified columns (separated by ,) to clipboard,
\& space separated \& space separated
\& \-\-ofs <char> Output field separator, used by \-A and \-C.
\& \&
\& Sort Mode Flags (mutually exclusive): \& Sort Mode Flags (mutually exclusive):
\& \-a, \-\-sort\-age sort according to age (duration) string \& \-a, \-\-sort\-age sort according to age (duration) string
\& \-D, \-\-sort\-desc Sort in descending order (default: ascending) \& \-D, \-\-sort\-desc Sort in descending order (default: ascending)
\& \-i, \-\-sort\-numeric sort according to string numerical value \& \-i, \-\-sort\-numeric sort according to string numerical value
\& \-t, \-\-sort\-time sort according to time string \& \-t, \-\-sort\-time sort according to time string
\& \&
\& Other Flags: \& Other Flags:
\& \-\-completion <shell> Generate the autocompletion script for <shell> \& \-r \-\-read\-file <file> Use <file> as input instead of STDIN
\& \-f, \-\-config <file> Configuration file (default: ~/.config/tablizer/config) \& \-\-completion <shell> Generate the autocompletion script for <shell>
\& \-d, \-\-debug Enable debugging \& \-f, \-\-config <file> Configuration file (default: ~/.config/tablizer/config)
\& \-h, \-\-help help for tablizer \& \-d, \-\-debug Enable debugging
\& \-m, \-\-man Display manual page \& \-h, \-\-help help for tablizer
\& \-V, \-\-version Print program version \& \-m, \-\-man Display manual page
\& \-V, \-\-version Print program version
.Ve .Ve
.SH "DESCRIPTION" .SH "DESCRIPTION"
.IX Header "DESCRIPTION" .IX Header "DESCRIPTION"
@@ -216,17 +218,17 @@ pattern. Hence:
\& kubectl get pods | tablizer \& kubectl get pods | tablizer
\& \&
\& # read a file \& # read a file
\& tablizer filename \& tablizer \-r filename
\& \&
\& # search for pattern in a file (works like grep) \& # search for pattern in a file (works like grep)
\& tablizer regex filename \& tablizer regex \-r filename
\& \&
\& # search for pattern in STDIN \& # search for pattern in STDIN
\& kubectl get pods | tablizer regex \& kubectl get pods | tablizer regex
.Ve .Ve
.PP .PP
The output looks like the original one but every header field will The output looks like the original one. You can add the option \fB\-n\fR,
have a numer associated with it, e.g.: then every header field will have a numer associated with it, e.g.:
.PP .PP
.Vb 1 .Vb 1
\& NAME(1) READY(2) STATUS(3) RESTARTS(4) AGE(5) \& NAME(1) READY(2) STATUS(3) RESTARTS(4) AGE(5)
@@ -242,7 +244,18 @@ columns you want to have in your output (see \s-1COLUMNS\s0:
You can specify the numbers in any order but output will always follow You can specify the numbers in any order but output will always follow
the original order. the original order.
.PP .PP
The numbering can be suppressed by using the \fB\-n\fR option. However, you may also just use the header names instead of numbers,
eg:
.PP
.Vb 1
\& kubectl get pods | tablizer \-cname,status
.Ve
.PP
You can also use regular expressions with \fB\-c\fR, eg:
.PP
.Vb 1
\& kubectl get pods | tablizer \-c \*(Aq[ae]\*(Aq
.Ve
.PP .PP
By default tablizer shows a header containing the names of each By default tablizer shows a header containing the names of each
column. This can be disabled using the \fB\-H\fR option. Be aware that column. This can be disabled using the \fB\-H\fR option. Be aware that

View File

@@ -5,47 +5,49 @@ tablizer - Manipulate tabular output of other programs
=head1 SYNOPSIS =head1 SYNOPSIS
Usage: Usage:
tablizer [regex,...] [file, ...] [flags] tablizer [regex,...] [-r file] [flags]
Operational Flags: Operational Flags:
-c, --columns string Only show the speficied columns (separated by ,) -c, --columns string Only show the speficied columns (separated by ,)
-v, --invert-match select non-matching rows -v, --invert-match select non-matching rows
-n, --numbering Enable header numbering -n, --numbering Enable header numbering
-N, --no-color Disable pattern highlighting -N, --no-color Disable pattern highlighting
-H, --no-headers Disable headers display -H, --no-headers Disable headers display
-s, --separator string Custom field separator -s, --separator <string> Custom field separator
-k, --sort-by int|name Sort by column (default: 1) -k, --sort-by <int|name> Sort by column (default: 1)
-z, --fuzzy Use fuzzy search [experimental] -z, --fuzzy Use fuzzy search [experimental]
-F, --filter field[!]=reg Filter given field with regex, can be used multiple times -F, --filter <field[!]=reg> Filter given field with regex, can be used multiple times
-T, --transpose-columns string Transpose the speficied columns (separated by ,) -T, --transpose-columns string Transpose the speficied columns (separated by ,)
-R, --regex-transposer /from/to/ Apply /search/replace/ regexp to fields given in -T -R, --regex-transposer </from/to/> Apply /search/replace/ regexp to fields given in -T
-I, --interactive Interactively filter and select rows -I, --interactive Interactively filter and select rows
Output Flags (mutually exclusive): Output Flags (mutually exclusive):
-X, --extended Enable extended output -X, --extended Enable extended output
-M, --markdown Enable markdown table output -M, --markdown Enable markdown table output
-O, --orgtbl Enable org-mode table output -O, --orgtbl Enable org-mode table output
-S, --shell Enable shell evaluable output -S, --shell Enable shell evaluable output
-Y, --yaml Enable yaml output -Y, --yaml Enable yaml output
-C, --csv Enable CSV output -C, --csv Enable CSV output
-A, --ascii Default output mode, ascii tabular -A, --ascii Default output mode, ascii tabular
-L, --hightlight-lines Use alternating background colors for tables -L, --hightlight-lines Use alternating background colors for tables
-y, --yank-columns Yank specified columns (separated by ,) to clipboard, -y, --yank-columns Yank specified columns (separated by ,) to clipboard,
space separated space separated
--ofs <char> Output field separator, used by -A and -C.
Sort Mode Flags (mutually exclusive): Sort Mode Flags (mutually exclusive):
-a, --sort-age sort according to age (duration) string -a, --sort-age sort according to age (duration) string
-D, --sort-desc Sort in descending order (default: ascending) -D, --sort-desc Sort in descending order (default: ascending)
-i, --sort-numeric sort according to string numerical value -i, --sort-numeric sort according to string numerical value
-t, --sort-time sort according to time string -t, --sort-time sort according to time string
Other Flags: Other Flags:
--completion <shell> Generate the autocompletion script for <shell> -r --read-file <file> Use <file> as input instead of STDIN
-f, --config <file> Configuration file (default: ~/.config/tablizer/config) --completion <shell> Generate the autocompletion script for <shell>
-d, --debug Enable debugging -f, --config <file> Configuration file (default: ~/.config/tablizer/config)
-h, --help help for tablizer -d, --debug Enable debugging
-m, --man Display manual page -h, --help help for tablizer
-V, --version Print program version -m, --man Display manual page
-V, --version Print program version
=head1 DESCRIPTION =head1 DESCRIPTION
@@ -77,16 +79,16 @@ pattern. Hence:
kubectl get pods | tablizer kubectl get pods | tablizer
# read a file # read a file
tablizer filename tablizer -r filename
# search for pattern in a file (works like grep) # search for pattern in a file (works like grep)
tablizer regex filename tablizer regex -r filename
# search for pattern in STDIN # search for pattern in STDIN
kubectl get pods | tablizer regex kubectl get pods | tablizer regex
The output looks like the original one but every header field will The output looks like the original one. You can add the option B<-n>,
have a numer associated with it, e.g.: then every header field will have a numer associated with it, e.g.:
NAME(1) READY(2) STATUS(3) RESTARTS(4) AGE(5) NAME(1) READY(2) STATUS(3) RESTARTS(4) AGE(5)
@@ -98,7 +100,14 @@ columns you want to have in your output (see L<COLUMNS>:
You can specify the numbers in any order but output will always follow You can specify the numbers in any order but output will always follow
the original order. the original order.
The numbering can be suppressed by using the B<-n> option. However, you may also just use the header names instead of numbers,
eg:
kubectl get pods | tablizer -cname,status
You can also use regular expressions with B<-c>, eg:
kubectl get pods | tablizer -c '[ae]'
By default tablizer shows a header containing the names of each By default tablizer shows a header containing the names of each
column. This can be disabled using the B<-H> option. Be aware that column. This can be disabled using the B<-H> option. Be aware that

15
vhsdemo/Makefile Normal file
View File

@@ -0,0 +1,15 @@
.PHONY: demo check clean-demo
VHS = vhs
clean-demo:
%.gif: %.tape
@echo "vhs $<"
env PATH=..:$(PATH) vhs $<
check:
ls -l ../tablizer
demo: check clean-demo demo.gif

BIN
vhsdemo/demo.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 MiB

157
vhsdemo/demo.tape Normal file
View File

@@ -0,0 +1,157 @@
# -*-sh-*-
Output demo.gif
Set FontSize 20
Set Width 1200
Set Height 1000
Set Theme { "name": "Whimsy", "black": "#535178", "red": "#ef6487", "green": "#5eca89", "yellow": "#fdd877", "blue": "#65aef7", "magenta": "#aa7ff0", "cyan": "#43c1be", "white": "#ffffff", "brightBlack": "#535178", "brightRed": "#ef6487", "brightGreen": "#5eca89", "brightYellow": "#fdd877", "brightBlue": "#65aef7", "brightMagenta": "#aa7ff0", "brightCyan": "#43c1be", "brightWhite": "#ffffff", "background": "#29283b", "foreground": "#b3b0d6", "selection": "#3d3c58", "cursor": "#b3b0d6" }
Set WindowBar Colorful
Set BorderRadius 10
Set Shell zsh
Set FontFamily "IBM Plex Mono"
Set CursorBlink false
Set PlaybackSpeed 1
Set TypingSpeed .05
# initialize
Hide
Type `PROMPT=''`
Enter
Type "setopt interactivecomments"
Enter
Type "autoload -U colors && colors"
Enter
Type `PS1="%{$fg[magenta]%}demo> %{$reset_color%}"`
Enter
Type "clear"
Enter
Show
Type "# Our input data"
Enter
Sleep 1s
Type "cat input | head -10"
Enter
Sleep 2s
Enter
Type "# Filter over all rows"
Enter
Sleep 1s
Type "tablizer Central < input"
Enter
Sleep 2s
Enter
Type "# Filter over all rows case insensitive"
Enter
Sleep 1s
Type "tablizer '/penc/i' < input"
Enter
Sleep 2s
Enter
Type "# Filter over specific column"
Enter
Sleep 1s
Type "tablizer -Fcost=4.99 < input"
Enter
Sleep 2s
Enter
Type "# Filter by regex on specific column"
Enter
Sleep 1s
Type "tablizer -Funits=Pen. < input"
Enter
Sleep 2s
Enter
Type "# Output as markdown"
Enter
Sleep 1s
Type "tablizer -Funits=Pen. -M < input"
Enter
Sleep 2s
Enter
Type "# Output as CSV"
Enter
Sleep 1s
Type "tablizer -Funits=Pen. -C < input"
Enter
Sleep 2s
Enter
Type "# Output as shell evaluable"
Enter
Sleep 1s
Type "tablizer -Funits=Pen. -S < input"
Enter
Sleep 2s
Type "bat eval.sh"
Enter
Sleep 2s
Type "tablizer -Funits=Pen. -S < input | ./eval.sh"
Enter
Sleep 2s
Enter
Type "# Reduce columns"
Enter
Sleep 1s
Type "tablizer -Funits=Pen. -c region,customer,units,count < input"
Enter
Sleep 2s
Enter
Type "# Sort by COUNT column numerically "
Enter
Sleep 1s
Type "tablizer -Funits=Pen. -c region,customer,units,count -kcount -i < input"
Enter
Sleep 2s
Enter
Type "# Do further filtering interactively"
Enter
Sleep 1s
Type "tablizer -Funits=Pen. -c region,customer,units,count -I -O < input"
Enter
Sleep 2s
Type "?"
Sleep 2s
Type "/"
Sleep 2s
Type "J"
Sleep 1s
Type "o"
Sleep 1s
Type "n"
Sleep 1s
Type "e"
Sleep 1s
Type "s"
Sleep 1s
Enter
Sleep 2s
Tab
Sleep 1s
Tab
Sleep 1s
Tab
Sleep 1s
Tab
Type "n"
Sleep 2s
Space
Sleep 1s
Down
Sleep 1s
Down
Sleep 1s
Space
Sleep 2s
Type "q"
Sleep 10s

5
vhsdemo/eval.sh Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/sh
while read LINE; do
eval "$LINE"; echo "$Customer ordered $Count ${Units}s"
done

44
vhsdemo/input Normal file
View File

@@ -0,0 +1,44 @@
Date Region Customer Units Count Cost Total
2016-01-06 East Jones Pencil 95 1.99 189.05
2016-01-23 Central Kivell Binder 50 19.99 999.50
2016-02-09 Central Jardine Pencil 36 4.99 179.64
2016-02-26 Central Gill Pen 27 19.99 539.73
2016-03-15 West Sorvino Pencil 56 2.99 167.44
2016-04-01 East Jones Binder 60 4.99 299.40
2016-04-18 Central Andrews Pencil 75 1.99 149.25
2016-05-05 Central Jardine Pencil 90 4.99 449.10
2016-05-22 West Thompson Pencil 32 1.99 63.68
2016-06-08 East Jones Binder 60 8.99 539.40
2016-06-25 Central Morgan Pencil 90 4.99 449.10
2016-07-12 East Howard Binder 29 1.99 57.71
2016-07-29 East Parent Binder 81 19.99 1619.19
2016-08-15 East Jones Pencil 35 4.99 174.65
2016-09-01 Central Smith Desk 2 125.00 250.00
2016-09-18 East Jones Pen Set 16 15.99 255.84
2016-10-05 Central Morgan Binder 28 8.99 251.72
2016-10-22 East Jones Pen 64 8.99 575.36
2016-11-08 East Parent Pen 15 19.99 299.85
2016-11-25 Central Kivell Pen Set 96 4.99 479.04
2016-12-12 Central Smith Pencil 67 1.29 86.43
2016-12-29 East Parent Pen Set 74 15.99 1183.26
2017-01-15 Central Gill Binder 46 8.99 413.54
2017-02-01 Central Smith Binder 87 15.00 1305.00
2017-02-18 East Jones Binder 4 4.99 19.96
2017-03-07 West Sorvino Binder 7 19.99 139.93
2017-03-24 Central Jardine Pen Set 50 4.99 249.50
2017-04-10 Central Andrews Pencil 66 1.99 131.34
2017-04-27 East Howard Pen 96 4.99 479.04
2017-05-14 Central Gill Pencil 53 1.29 68.37
2017-05-31 Central Gill Binder 80 8.99 719.20
2017-06-17 Central Kivell Desk 5 125.00 625.00
2017-07-04 East Jones Pen Set 62 4.99 309.38
2017-07-21 Central Morgan Pen Set 55 12.49 686.95
2017-08-07 Central Kivell Pen Set 42 23.95 1005.90
2017-08-24 West Sorvino Desk 3 275.00 825.00
2017-09-10 Central Gill Pencil 7 1.29 9.03
2017-09-27 West Sorvino Pen 76 1.99 151.24
2017-10-14 West Thompson Binder 57 19.99 1139.43
2017-10-31 Central Andrews Pencil 14 1.29 18.06
2017-11-17 Central Jardine Binder 11 4.99 54.89
2017-12-04 Central Jardine Binder 94 19.99 1879.06
2017-12-21 Central Andrews Binder 28 4.99 139.72