Compare commits

...

9 Commits

Author SHA1 Message Date
200f1f32f8 using patched tiagomeol/go-clipboard/clipboard, fixes #37 2025-01-28 14:40:17 +01:00
768a19b4d6 fine tuning, added test, which hangs, but yanking works anyway 2025-01-23 13:59:02 +01:00
Thomas von Dein
dc718392b6 fix-import 2025-01-22 23:15:12 +01:00
Thomas von Dein
e8f4fef41c fix #37: make yank portable 2025-01-22 23:12:42 +01:00
82f54c120d catch err 2025-01-21 18:42:04 +01:00
T.v.Dein
2d5799e2f2 Use primary clipboard on unix 2025-01-20 21:27:26 +01:00
8e33cadcaa add -y 2025-01-20 19:28:19 +01:00
03f3225f24 build release binaries using ci workflow 2025-01-18 10:51:28 +01:00
63c7ef26b6 add -k<name> and sort by multiple columns support, fixes #34 2025-01-15 18:53:34 +01:00
20 changed files with 364 additions and 61 deletions

32
.github/workflows/release.yaml vendored Normal file
View File

@@ -0,0 +1,32 @@
name: build-and-test
on:
push:
tags:
- "*"
jobs:
release:
name: Build Release Assets
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Go
uses: actions/setup-go@v1
with:
go-version: 1.22.11
- name: Build the executables
run: ./mkrel.sh tablizer ${{ github.ref_name}}
- name: List the executables
run: ls -l ./releases
- name: Upload the binaries
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
tag: ${{ github.ref_name }}
file: ./releases/*
file_glob: true

View File

@@ -53,8 +53,7 @@ buildlocal:
go build -ldflags "-X 'github.com/tlinden/tablizer/cfg.VERSION=$(VERSION)'"
release:
./mkrel.sh $(tool) $(version)
gh release create $(version) --generate-notes releases/*
gh release create $(version) --generate-notes
install: buildlocal
install -d -o $(UID) -g $(GID) $(PREFIX)/bin
@@ -70,7 +69,7 @@ test:
singletest:
@echo "Call like this: 'make singletest TEST=TestPrepareColumns MOD=lib'"
go test -run $(TEST) github.com/tlinden/tablizer/$(MOD)
go test -run $(TEST) github.com/tlinden/tablizer/$(MOD) $(OPTS)
cover-report:
go test ./... -cover -coverprofile=coverage.out

View File

@@ -35,6 +35,8 @@ Output Flags (mutually exclusive):
-C, --csv Enable CSV output
-A, --ascii Default output mode, ascii tabular
-L, --hightlight-lines Use alternating background colors for tables
-y, --yank-columns Yank specified columns (separated by ,) to clipboard,
space separated
Sort Mode Flags (mutually exclusive):
-a, --sort-age sort according to age (duration) string

View File

@@ -28,7 +28,7 @@ import (
)
const DefaultSeparator string = `(\s\s+|\t)`
const Version string = "v1.3.0"
const Version string = "v1.3.1"
const MAXPARTS = 2
var DefaultConfigfile = os.Getenv("HOME") + "/.config/tablizer/config"
@@ -59,6 +59,8 @@ type Config struct {
NoHeaders bool
Columns string
UseColumns []int
YankColumns string
UseYankColumns []int
Separator string
OutputMode int
InvertMatch bool
@@ -67,9 +69,10 @@ type Config struct {
UseFuzzySearch bool
UseHighlight bool
SortMode string
SortDescending bool
SortByColumn int
SortMode string
SortDescending bool
SortByColumn string // 1,2
UseSortByColumn []int // []int{1,2}
TransposeColumns string // 1,2
UseTransposeColumns []int // []int{1,2}

View File

@@ -147,11 +147,13 @@ func Execute() {
"Custom field separator")
rootCmd.PersistentFlags().StringVarP(&conf.Columns, "columns", "c", "",
"Only show the speficied columns (separated by ,)")
rootCmd.PersistentFlags().StringVarP(&conf.YankColumns, "yank-columns", "y", "",
"Yank the speficied columns (separated by ,) to the clipboard")
rootCmd.PersistentFlags().StringVarP(&conf.TransposeColumns, "transpose-columns", "T", "",
"Transpose the speficied columns (separated by ,)")
// sort options
rootCmd.PersistentFlags().IntVarP(&conf.SortByColumn, "sort-by", "k", 0,
rootCmd.PersistentFlags().StringVarP(&conf.SortByColumn, "sort-by", "k", "",
"Sort by column (default: 1)")
// sort mode, only 1 allowed

View File

@@ -15,7 +15,7 @@ SYNOPSIS
-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)
-k, --sort-by int|name Sort by column (default: 1)
-z, --fuzzy Use fuzzy search [experimental]
-F, --filter field=reg Filter given field with regex, can be used multiple times
-T, --transpose-columns string Transpose the speficied columns (separated by ,)
@@ -30,6 +30,8 @@ SYNOPSIS
-C, --csv Enable CSV output
-A, --ascii Default output mode, ascii tabular
-L, --hightlight-lines Use alternating background colors for tables
-y, --yank-columns Yank specified columns (separated by ,) to clipboard,
space separated
Sort Mode Flags (mutually exclusive):
-a, --sort-age sort according to age (duration) string
@@ -103,10 +105,19 @@ DESCRIPTION
highlighted. You can disable this behavior with the -N option.
Use the -k option to specify by which column to sort the tabular data
(as in GNU sort(1)). The default sort column is the first one. To
disable sorting at all, supply 0 (Zero) to -k. The default sort order is
ascending. You can change this to descending order using the option -D.
The default sort order is by string, but there are other sort modes:
(as in GNU sort(1)). The default sort column is the first one. You can
specify column numbers or names. Column numbers start with 1, names are
case insensitive. You can specify multiple columns separated by comma to
sort, but the type must be the same. For example if you want to sort
numerically, all columns must be numbers. If you use column numbers,
then be aware, that these are the numbers before column extraction. For
example if you have a table with 4 columns and specify "-c4", then only
1 column (the fourth) will be printed, however if you want to sort by
this column, you'll have to specify "-k4".
The default sort order is ascending. You can change this to descending
order using the option -D. The default sort order is by alphanumeric
string, but there are other sort modes:
-a --sort-age
Sorts duration strings like "1d4h32m51s".
@@ -258,6 +269,18 @@ DESCRIPTION
markdown which prints a Markdown table, yaml, which prints yaml encoding
and CSV mode, which prints a comma separated value file.
PUT FIELDS TO CLIPBOARD
You can let tablizer put fields to the clipboard using the option "-y".
This best fits the use-case when the result of your filtering yields
just one row. For example:
cloudctl cluster ls | tablizer -yid matchbox
If "matchbox" matches one cluster, you can immediately use the id of
that cluster somewhere else and paste it. Of course, if there are
multiple matches, then all id's will be put into the clipboard separated
by one space.
ENVIRONMENT VARIABLES
tablizer supports certain environment variables which use can use to
influence program behavior. Commandline flags have always precedence
@@ -392,7 +415,7 @@ Operational Flags:
-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)
-k, --sort-by int|name Sort by column (default: 1)
-z, --fuzzy Use fuzzy search [experimental]
-F, --filter field=reg Filter given field with regex, can be used multiple times
-T, --transpose-columns string Transpose the speficied columns (separated by ,)
@@ -407,6 +430,8 @@ Output Flags (mutually exclusive):
-C, --csv Enable CSV output
-A, --ascii Default output mode, ascii tabular
-L, --hightlight-lines Use alternating background colors for tables
-y, --yank-columns Yank specified columns (separated by ,) to clipboard,
space separated
Sort Mode Flags (mutually exclusive):
-a, --sort-age sort according to age (duration) string

3
go.mod
View File

@@ -5,6 +5,7 @@ go 1.22
require (
github.com/alecthomas/repr v0.4.0
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de
github.com/atotto/clipboard v0.1.4
github.com/gookit/color v1.5.4
github.com/hashicorp/hcl/v2 v2.23.0
github.com/lithammer/fuzzysearch v1.1.8
@@ -22,8 +23,10 @@ require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/tiagomelo/go-clipboard v0.1.2-0.20250126153310-fcc1f95408cf // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
github.com/zclconf/go-cty v1.13.3 // indirect
golang.org/x/mod v0.18.0 // indirect

8
go.sum
View File

@@ -8,6 +8,8 @@ github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de h1:FxWPpzIjnTlhPwqqXc4/vE0f7GvRjuAsbW+HOIe8KnA=
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de/go.mod h1:DCaWoUhZrYW9p1lxo/cm8EmUOOzAPSEZNGF2DK1dJgw=
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -32,6 +34,8 @@ github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzC
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
@@ -49,6 +53,10 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tiagomelo/go-clipboard v0.1.1 h1:nddQ5DsEnKW0KdzTILhbLpSq3e9y2dkJXEOtsMs6H7A=
github.com/tiagomelo/go-clipboard v0.1.1/go.mod h1:kXtjJBIMimZaGbxmcKZ8+JqK+acSNf5tAJiChlZBOr8=
github.com/tiagomelo/go-clipboard v0.1.2-0.20250126153310-fcc1f95408cf h1:csb/+rmJBAtOP6OP+9soTnwJVuhlUpedjb5dPlNZasY=
github.com/tiagomelo/go-clipboard v0.1.2-0.20250126153310-fcc1f95408cf/go.mod h1:kXtjJBIMimZaGbxmcKZ8+JqK+acSNf5tAJiChlZBOr8=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=

View File

@@ -77,6 +77,14 @@ func PrepareColumns(conf *cfg.Config, data *Tabdata) error {
conf.UseColumns = usecolumns
// -y columns
useyankcolumns, err := PrepareColumnVars(conf.YankColumns, data)
if err != nil {
return err
}
conf.UseYankColumns = useyankcolumns
return nil
}
@@ -99,6 +107,19 @@ func PrepareTransposerColumns(conf *cfg.Config, data *Tabdata) error {
return nil
}
// output option, prepare -k1,2 sort fields
func PrepareSortColumns(conf *cfg.Config, data *Tabdata) error {
// -c columns
usecolumns, err := PrepareColumnVars(conf.SortByColumn, data)
if err != nil {
return err
}
conf.UseSortByColumn = usecolumns
return nil
}
func PrepareColumnVars(columns string, data *Tabdata) ([]int, error) {
if columns == "" {
return nil, nil

View File

@@ -48,6 +48,11 @@ func ProcessFiles(conf *cfg.Config, args []string) error {
return err
}
err = PrepareSortColumns(conf, &data)
if err != nil {
return err
}
err = PrepareColumns(conf, &data)
if err != nil {
return err

View File

@@ -1,5 +1,5 @@
/*
Copyright © 2022 Thomas von Dein
Copyright © 2022-2025 Thomas von Dein
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -33,15 +33,20 @@ import (
)
func printData(writer io.Writer, conf cfg.Config, data *Tabdata) {
// add numbers to headers and remove this we're not interested in
// Sort the data first, before headers+entries are being
// reduced. That way the user can specify any valid column to sort
// by, independently if it's being used for display or not.
sortTable(conf, data)
// put one or more columns into clipboard
yankColumns(conf, data)
// add numbers to headers and remove those we're not interested in
numberizeAndReduceHeaders(conf, data)
// remove unwanted columns, if any
reduceColumns(conf, data)
// sort the data
sortTable(conf, data)
switch conf.OutputMode {
case cfg.Extended:
printExtendedData(writer, conf, data)

View File

@@ -63,7 +63,7 @@ var tests = []struct {
name string // so we can identify which one fails, can be the same
// for multiple tests, because flags will be appended to the name
sortby string // empty == default
column int // sort by this column, 0 == default first or NO Sort
column int // sort by this column (numbers start by 1)
desc bool // sort in descending order, default == ascending
nonum bool // hide numbering
mode int // shell, orgtbl, etc. empty == default: ascii
@@ -162,7 +162,7 @@ DURATION(2): 33d12h
//------------------------ SORT TESTS
{
name: "sortbycolumn",
name: "sortbycolumn3",
column: 3,
sortby: "numeric",
desc: false,
@@ -173,7 +173,7 @@ beta 1d10h5m1s 33 3/1/2014
alpha 4h35m 170 2013-Feb-03`,
},
{
name: "sortbycolumn",
name: "sortbycolumn4",
column: 4,
sortby: "time",
desc: false,
@@ -184,7 +184,7 @@ alpha 4h35m 170 2013-Feb-03
beta 1d10h5m1s 33 3/1/2014`,
},
{
name: "sortbycolumn",
name: "sortbycolumn2",
column: 2,
sortby: "duration",
desc: false,
@@ -251,15 +251,14 @@ DURATION(2) WHEN(4)
func TestPrinter(t *testing.T) {
for _, testdata := range tests {
testname := fmt.Sprintf("print-sortcol-%d-desc-%t-sortby-%s-mode-%d-usecolumns-%s",
testdata.column, testdata.desc, testdata.sortby, testdata.mode, testdata.usecolstr)
testname := fmt.Sprintf("print-%s-%d-desc-%t-sortby-%s-mode-%d-usecolumns-%s",
testdata.name, testdata.column, testdata.desc, testdata.sortby, testdata.mode, testdata.usecolstr)
t.Run(testname, func(t *testing.T) {
// replaces os.Stdout, but we ignore it
var writer bytes.Buffer
// cmd flags
conf := cfg.Config{
SortByColumn: testdata.column,
SortDescending: testdata.desc,
SortMode: testdata.sortby,
OutputMode: testdata.mode,
@@ -268,6 +267,10 @@ func TestPrinter(t *testing.T) {
NoColor: true,
}
if testdata.column > 0 {
conf.UseSortByColumn = []int{testdata.column}
}
conf.ApplyDefaults()
// the test checks the len!

View File

@@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package lib
import (
"cmp"
"regexp"
"sort"
"strconv"
@@ -27,34 +28,41 @@ import (
)
func sortTable(conf cfg.Config, data *Tabdata) {
if conf.SortByColumn <= 0 {
if len(conf.UseSortByColumn) == 0 {
// no sorting wanted
return
}
// slightly modified here to match internal array indicies
col := conf.SortByColumn
col-- // ui starts counting by 1, but use 0 internally
// sanity checks
if len(data.entries) == 0 {
return
}
if col >= len(data.headers) {
// fall back to default column
col = 0
}
// actual sorting
sort.SliceStable(data.entries, func(i, j int) bool {
return compare(&conf, data.entries[i][col], data.entries[j][col])
// holds the result of a sort of one column
comparators := []int{}
// iterate over all columns to be sorted, conf.SortMode must be identical!
for _, column := range conf.UseSortByColumn {
comparators = append(comparators, compare(&conf, data.entries[i][column-1], data.entries[j][column-1]))
}
// return the combined result
res := cmp.Or(comparators...)
switch res {
case 0:
return true
default:
return false
}
})
}
// config is not modified here, but it would be inefficient to copy it every loop
func compare(conf *cfg.Config, left string, right string) bool {
func compare(conf *cfg.Config, left string, right string) int {
var comp bool
switch conf.SortMode {
@@ -88,7 +96,12 @@ func compare(conf *cfg.Config, left string, right string) bool {
comp = !comp
}
return comp
switch comp {
case true:
return 0
default:
return 1
}
}
/*

View File

@@ -53,18 +53,18 @@ func TestCompare(t *testing.T) {
mode string
a string
b string
want bool
want int
desc bool
}{
// ascending
{"numeric", "10", "20", true, false},
{"duration", "2d4h5m", "45m", false, false},
{"time", "12/24/2022", "1/1/1970", false, false},
{"numeric", "10", "20", 0, false},
{"duration", "2d4h5m", "45m", 1, false},
{"time", "12/24/2022", "1/1/1970", 1, false},
// descending
{"numeric", "10", "20", false, true},
{"duration", "2d4h5m", "45m", true, true},
{"time", "12/24/2022", "1/1/1970", true, true},
{"numeric", "10", "20", 1, true},
{"duration", "2d4h5m", "45m", 0, true},
{"time", "12/24/2022", "1/1/1970", 0, true},
}
for _, testdata := range tests {
@@ -75,7 +75,7 @@ func TestCompare(t *testing.T) {
c := cfg.Config{SortMode: testdata.mode, SortDescending: testdata.desc}
got := compare(&c, testdata.a, testdata.b)
if got != testdata.want {
t.Errorf("got %t, want %t", got, testdata.want)
t.Errorf("got %d, want %d", got, testdata.want)
}
})
}

51
lib/yank.go Normal file
View File

@@ -0,0 +1,51 @@
/*
Copyright © 2022-2025 Thomas von Dein
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package lib
import (
"log"
"strings"
"github.com/tiagomelo/go-clipboard/clipboard"
"github.com/tlinden/tablizer/cfg"
)
func yankColumns(conf cfg.Config, data *Tabdata) {
var yank []string
if len(data.entries) == 0 || len(conf.UseYankColumns) == 0 {
return
}
for _, row := range data.entries {
for i, field := range row {
for _, idx := range conf.UseYankColumns {
if i == idx-1 {
yank = append(yank, field)
}
}
}
}
if len(yank) > 0 {
cb := clipboard.New(clipboard.ClipboardOptions{Primary: true})
if err := cb.CopyText(strings.Join(yank, " ")); err != nil {
log.Fatalln("error writing string to clipboard:", err)
}
}
}

72
lib/yank_test.go Normal file
View File

@@ -0,0 +1,72 @@
/*
Copyright © 2025 Thomas von Dein
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package lib
import (
"bytes"
"fmt"
"testing"
"github.com/tiagomelo/go-clipboard/clipboard"
"github.com/tlinden/tablizer/cfg"
)
var yanktests = []struct {
name string
yank []int // -y$colum,$column... after processing
filter string
expect string
}{
{
name: "one",
yank: []int{1},
filter: "beta",
},
}
func DISABLED_TestYankColumns(t *testing.T) {
cb := clipboard.New()
for _, testdata := range yanktests {
testname := fmt.Sprintf("yank-%s-filter-%s",
testdata.name, testdata.filter)
t.Run(testname, func(t *testing.T) {
conf := cfg.Config{
OutputMode: cfg.ASCII,
UseYankColumns: testdata.yank,
NoColor: true,
}
conf.ApplyDefaults()
data := newData() // defined in printer_test.go, reused here
var writer bytes.Buffer
printData(&writer, conf, &data)
got, err := cb.PasteText()
if err != nil {
t.Errorf("failed to fetch yanked text from clipboard")
}
if got != testdata.expect {
t.Errorf("not yanked correctly:\n+++ got:\n%s\n+++ want:\n%s",
got, testdata.expect)
}
})
}
}

6
t/testtable3 Normal file
View File

@@ -0,0 +1,6 @@
NAME READY STATUS STARTS AGE
alertmanager-kube-prometheus-alertmanager-0 2/2 Running 35 11d
kube-prometheus-blackbox-exporter-5d85b5d8f4-tskh7 1/1 Running 17 1h44m
grafana-fcc54cbc9-bk7s8 1/1 Running 17 1d
kube-prometheus-kube-state-metrics-b4cd9487-75p7f 1/1 Running 20 45m
kube-prometheus-node-exporter-bfzpl 1/1 Running 17 54s

4
t/testtable4 Normal file
View File

@@ -0,0 +1,4 @@
ONE TWO
1 4
3 1
5 2

View File

@@ -133,7 +133,7 @@
.\" ========================================================================
.\"
.IX Title "TABLIZER 1"
.TH TABLIZER 1 "2025-01-14" "1" "User Commands"
.TH TABLIZER 1 "2025-01-23" "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
@@ -153,7 +153,7 @@ tablizer \- Manipulate tabular output of other programs
\& \-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)
\& \-k, \-\-sort\-by int|name Sort by column (default: 1)
\& \-z, \-\-fuzzy Use fuzzy search [experimental]
\& \-F, \-\-filter field=reg Filter given field with regex, can be used multiple times
\& \-T, \-\-transpose\-columns string Transpose the speficied columns (separated by ,)
@@ -168,6 +168,8 @@ tablizer \- Manipulate tabular output of other programs
\& \-C, \-\-csv Enable CSV output
\& \-A, \-\-ascii Default output mode, ascii tabular
\& \-L, \-\-hightlight\-lines Use alternating background colors for tables
\& \-y, \-\-yank\-columns Yank specified columns (separated by ,) to clipboard,
\& space separated
\&
\& Sort Mode Flags (mutually exclusive):
\& \-a, \-\-sort\-age sort according to age (duration) string
@@ -250,11 +252,20 @@ By default, if a \fBpattern\fR has been speficied, matches will be
highlighted. You can disable this behavior with the \fB\-N\fR option.
.PP
Use the \fB\-k\fR option to specify by which column to sort the tabular
data (as in \s-1GNU\s0 \fBsort\fR\|(1)). The default sort column is the first one. To
disable sorting at all, supply 0 (Zero) to \-k. The default sort order
is ascending. You can change this to descending order using the option
\&\fB\-D\fR. The default sort order is by string, but there are other sort
modes:
data (as in \s-1GNU\s0 \fBsort\fR\|(1)). The default sort column is the first
one. You can specify column numbers or names. Column numbers start
with 1, names are case insensitive. You can specify multiple columns
separated by comma to sort, but the type must be the same. For example
if you want to sort numerically, all columns must be numbers. If you
use column numbers, then be aware, that these are the numbers before
column extraction. For example if you have a table with 4 columns and
specify \f(CW\*(C`\-c4\*(C'\fR, then only 1 column (the fourth) will be printed,
however if you want to sort by this column, you'll have to specify
\&\f(CW\*(C`\-k4\*(C'\fR.
.PP
The default sort order is ascending. You can change this to
descending order using the option \fB\-D\fR. The default sort order is by
alphanumeric string, but there are other sort modes:
.IP "\fB\-a \-\-sort\-age\fR" 4
.IX Item "-a --sort-age"
Sorts duration strings like \*(L"1d4h32m51s\*(R".
@@ -433,6 +444,20 @@ more output modes available: \fBorgtbl\fR which prints an Emacs org-mode
table and \fBmarkdown\fR which prints a Markdown table, \fByaml\fR, which
prints yaml encoding and \s-1CSV\s0 mode, which prints a comma separated
value file.
.SS "\s-1PUT FIELDS TO CLIPBOARD\s0"
.IX Subsection "PUT FIELDS TO CLIPBOARD"
You can let tablizer put fields to the clipboard using the option
\&\f(CW\*(C`\-y\*(C'\fR. This best fits the use-case when the result of your filtering
yields just one row. For example:
.PP
.Vb 1
\& cloudctl cluster ls | tablizer \-yid matchbox
.Ve
.PP
If \*(L"matchbox\*(R" matches one cluster, you can immediately use the id of
that cluster somewhere else and paste it. Of course, if there are
multiple matches, then all id's will be put into the clipboard
separated by one space.
.SS "\s-1ENVIRONMENT VARIABLES\s0"
.IX Subsection "ENVIRONMENT VARIABLES"
\&\fBtablizer\fR supports certain environment variables which use can use

View File

@@ -14,7 +14,7 @@ tablizer - Manipulate tabular output of other programs
-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)
-k, --sort-by int|name Sort by column (default: 1)
-z, --fuzzy Use fuzzy search [experimental]
-F, --filter field=reg Filter given field with regex, can be used multiple times
-T, --transpose-columns string Transpose the speficied columns (separated by ,)
@@ -29,6 +29,8 @@ tablizer - Manipulate tabular output of other programs
-C, --csv Enable CSV output
-A, --ascii Default output mode, ascii tabular
-L, --hightlight-lines Use alternating background colors for tables
-y, --yank-columns Yank specified columns (separated by ,) to clipboard,
space separated
Sort Mode Flags (mutually exclusive):
-a, --sort-age sort according to age (duration) string
@@ -106,11 +108,20 @@ By default, if a B<pattern> has been speficied, matches will be
highlighted. You can disable this behavior with the B<-N> option.
Use the B<-k> option to specify by which column to sort the tabular
data (as in GNU sort(1)). The default sort column is the first one. To
disable sorting at all, supply 0 (Zero) to -k. The default sort order
is ascending. You can change this to descending order using the option
B<-D>. The default sort order is by string, but there are other sort
modes:
data (as in GNU sort(1)). The default sort column is the first
one. You can specify column numbers or names. Column numbers start
with 1, names are case insensitive. You can specify multiple columns
separated by comma to sort, but the type must be the same. For example
if you want to sort numerically, all columns must be numbers. If you
use column numbers, then be aware, that these are the numbers before
column extraction. For example if you have a table with 4 columns and
specify C<-c4>, then only 1 column (the fourth) will be printed,
however if you want to sort by this column, you'll have to specify
C<-k4>.
The default sort order is ascending. You can change this to
descending order using the option B<-D>. The default sort order is by
alphanumeric string, but there are other sort modes:
=over
@@ -281,6 +292,19 @@ table and B<markdown> which prints a Markdown table, B<yaml>, which
prints yaml encoding and CSV mode, which prints a comma separated
value file.
=head2 PUT FIELDS TO CLIPBOARD
You can let tablizer put fields to the clipboard using the option
C<-y>. This best fits the use-case when the result of your filtering
yields just one row. For example:
cloudctl cluster ls | tablizer -yid matchbox
If "matchbox" matches one cluster, you can immediately use the id of
that cluster somewhere else and paste it. Of course, if there are
multiple matches, then all id's will be put into the clipboard
separated by one space.
=head2 ENVIRONMENT VARIABLES
B<tablizer> supports certain environment variables which use can use