Compare commits

..

13 Commits

40 changed files with 577 additions and 297 deletions

View File

@@ -1,38 +0,0 @@
name: build-and-test-tablizer
on: [push]
jobs:
build:
strategy:
matrix:
version: ['1.24']
os: [ubuntu-latest, macos-latest, windows-latest]
name: Build
runs-on: ${{ matrix.os }}
steps:
- name: Set up Go ${{ matrix.version }}
uses: actions/setup-go@v6
with:
go-version: '${{ matrix.version }}'
id: go
- name: checkout
uses: actions/checkout@v5
- name: build
run: make
- name: test
run: make test
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v6
with:
go-version: 1.24
- uses: actions/checkout@v5
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
with:
skip-cache: true

View File

@@ -1,87 +0,0 @@
name: build-release
on:
push:
tags:
- "v*.*.*"
jobs:
release:
name: Build Release Assets
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: 1.24.0
- 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
- name: Build Changelog
id: github_release
uses: mikepenz/release-changelog-builder-action@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
mode: "PR"
configurationJson: |
{
"template": "#{{CHANGELOG}}\n\n**Full Changelog**: #{{RELEASE_DIFF}}",
"pr_template": "- #{{TITLE}} (##{{NUMBER}}) by #{{AUTHOR}}\n#{{BODY}}",
"empty_template": "- no changes",
"categories": [
{
"title": "## New Features",
"labels": ["add", "feature"]
},
{
"title": "## Bug Fixes",
"labels": ["fix", "bug", "revert"]
},
{
"title": "## Documentation Enhancements",
"labels": ["doc"]
},
{
"title": "## Refactoring Efforts",
"labels": ["refactor"]
},
{
"title": "## Miscellaneus Changes",
"labels": []
}
],
"ignore_labels": [
"duplicate", "good first issue", "help wanted", "invalid", "question", "wontfix"
],
"label_extractor": [
{
"pattern": "(.) (.+)",
"target": "$1"
},
{
"pattern": "(.) (.+)",
"target": "$1",
"on_property": "title"
}
]
}
- name: Create Release
uses: softprops/action-gh-release@v2
with:
body: ${{steps.github_release.outputs.changelog}}

72
.goreleaser.yaml Normal file
View File

@@ -0,0 +1,72 @@
# vim: set ts=2 sw=2 tw=0 fo=cnqoj
version: 2
before:
hooks:
- go mod tidy
gitea_urls:
api: https://codeberg.org/api/v1
download: https://codeberg.org
builds:
- env:
- CGO_ENABLED=0
goos:
- linux
- windows
- darwin
- freebsd
goarch:
- amd64
- arm64
archives:
- formats: [tar.gz]
# this name template makes the OS and Arch compatible with the results of `uname`.
name_template: >-
{{ .ProjectName }}_
{{- title .Os }}_
{{- if eq .Arch "amd64" }}x86_64
{{- else if eq .Arch "386" }}i386
{{- else }}{{ .Arch }}{{ end }}
{{- if .Arm }}v{{ .Arm }}{{ end }}_{{ .Tag }}
# use zip for windows archives
format_overrides:
- goos: windows
formats: [zip]
- goos: linux
formats: [tar.gz,binary]
files:
- src: "*.md"
strip_parent: true
- src: "docs/*"
strip_parent: true
- src: Makefile.dist
dst: Makefile
wrap_in_directory: true
changelog:
sort: asc
filters:
exclude:
- "^docs:"
- "^test:"
groups:
- title: Improved
regexp: '^.*?(feat|add|new)(\([[:word:]]+\))??!?:.+$'
order: 0
- title: Fixed
regexp: '^.*?(bug|fix)(\([[:word:]]+\))??!?:.+$'
order: 1
- title: Changed
order: 999
release:
header: "# Release Notes"
footer: >-
---
Full Changelog: [{{ .PreviousTag }}...{{ .Tag }}](https://codeberg.org/scip/tablizer/compare/{{ .PreviousTag }}...{{ .Tag }})

36
.woodpecker/build.yaml Normal file
View File

@@ -0,0 +1,36 @@
matrix:
platform:
- linux/amd64
goversion:
- 1.24
labels:
platform: ${platform}
steps:
build:
when:
event: [push]
image: golang:${goversion}
commands:
- go get
- go build
linter:
when:
event: [push]
image: golang:${goversion}
commands:
- curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.5.0
- golangci-lint --version
- golangci-lint run ./...
depends_on: [build]
test:
when:
event: [push]
image: golang:${goversion}
commands:
- go get
- go test -v -cover
depends_on: [build,linter]

15
.woodpecker/release.yaml Normal file
View File

@@ -0,0 +1,15 @@
# build release
labels:
platform: linux/amd64
steps:
goreleaser:
image: goreleaser/goreleaser
when:
event: [tag]
environment:
GITEA_TOKEN:
from_secret: DEPLOY_TOKEN
commands:
- goreleaser release --clean --verbose

View File

@@ -4,9 +4,9 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org). The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org).
## [v1.0.14](https://github.com/TLINDEN/tablizer/tree/v1.0.14) - 2023-01-23 ## [v1.0.14](https://codeberg.org/scip/tablizer/tree/v1.0.14) - 2023-01-23
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.13...v1.0.14) [Full Changelog](https://codeberg.org/scip/tablizer/compare/v1.0.13...v1.0.14)
### Fixed ### Fixed
@@ -28,9 +28,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
- updated dependencies (go module versions) - updated dependencies (go module versions)
## [v1.0.13](https://github.com/TLINDEN/tablizer/tree/v1.0.13) - 2022-11-03 ## [v1.0.13](https://codeberg.org/scip/tablizer/tree/v1.0.13) - 2022-11-03
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.12...v1.0.13) [Full Changelog](https://codeberg.org/scip/tablizer/compare/v1.0.12...v1.0.13)
### Added ### Added
@@ -47,9 +47,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
manpage. manpage.
## [v1.0.12](https://github.com/TLINDEN/tablizer/tree/v1.0.12) - 2022-10-25 ## [v1.0.12](https://codeberg.org/scip/tablizer/tree/v1.0.12) - 2022-10-25
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.11...v1.0.12) [Full Changelog](https://codeberg.org/scip/tablizer/compare/v1.0.11...v1.0.12)
### Added ### Added
@@ -72,14 +72,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
### Fixed ### Fixed
- Fixed [Bug #5](https://github.com/TLINDEN/tablizer/issues/5), where - Fixed [Bug #5](https://codeberg.org/scip/tablizer/issues/5), where
matches have not been highlighted correctly in some rare cases. matches have not been highlighted correctly in some rare cases.
## [v1.0.11](https://github.com/TLINDEN/tablizer/tree/v1.0.11) - 2022-10-19 ## [v1.0.11](https://codeberg.org/scip/tablizer/tree/v1.0.11) - 2022-10-19
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.10...v1.0.11) [Full Changelog](https://codeberg.org/scip/tablizer/compare/v1.0.10...v1.0.11)
### Added ### Added
@@ -101,9 +101,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
## [v1.0.10](https://github.com/TLINDEN/tablizer/tree/v1.0.10) - 2022-10-15 ## [v1.0.10](https://codeberg.org/scip/tablizer/tree/v1.0.10) - 2022-10-15
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.9...v1.0.10) [Full Changelog](https://codeberg.org/scip/tablizer/compare/v1.0.9...v1.0.10)
### Added ### Added
@@ -123,9 +123,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
## [v1.0.9](https://github.com/TLINDEN/tablizer/tree/v1.0.9) - 2022-10-14 ## [v1.0.9](https://codeberg.org/scip/tablizer/tree/v1.0.9) - 2022-10-14
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.8...v1.0.9) [Full Changelog](https://codeberg.org/scip/tablizer/compare/v1.0.8...v1.0.9)
### Added ### Added
@@ -137,9 +137,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
## [v1.0.8](https://github.com/TLINDEN/tablizer/tree/v1.0.8) - 2022-10-13 ## [v1.0.8](https://codeberg.org/scip/tablizer/tree/v1.0.8) - 2022-10-13
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.7...v1.0.8) [Full Changelog](https://codeberg.org/scip/tablizer/compare/v1.0.7...v1.0.8)
### Added ### Added
@@ -147,9 +147,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
## [v1.0.7](https://github.com/TLINDEN/tablizer/tree/v1.0.7) - 2022-10-11 ## [v1.0.7](https://codeberg.org/scip/tablizer/tree/v1.0.7) - 2022-10-11
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.6...v1.0.7) [Full Changelog](https://codeberg.org/scip/tablizer/compare/v1.0.6...v1.0.7)
### Added ### Added
@@ -165,9 +165,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
## [v1.0.6](https://github.com/TLINDEN/tablizer/tree/v1.0.6) - 2022-10-05 ## [v1.0.6](https://codeberg.org/scip/tablizer/tree/v1.0.6) - 2022-10-05
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.5...v1.0.6) [Full Changelog](https://codeberg.org/scip/tablizer/compare/v1.0.5...v1.0.6)
### Added ### Added
@@ -183,9 +183,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
## [v1.0.5](https://github.com/TLINDEN/tablizer/tree/v1.0.5) - 2022-10-05 ## [v1.0.5](https://codeberg.org/scip/tablizer/tree/v1.0.5) - 2022-10-05
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.4...v1.0.5) [Full Changelog](https://codeberg.org/scip/tablizer/compare/v1.0.4...v1.0.5)
### Added ### Added
@@ -203,9 +203,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
## [v1.0.4](https://github.com/TLINDEN/tablizer/tree/v1.0.4) - 2022-10-04 ## [v1.0.4](https://codeberg.org/scip/tablizer/tree/v1.0.4) - 2022-10-04
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.3...v1.0.4) [Full Changelog](https://codeberg.org/scip/tablizer/compare/v1.0.3...v1.0.4)
### Added ### Added
@@ -221,9 +221,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
## [v1.0.3](https://github.com/TLINDEN/tablizer/tree/v1.0.3) - 2022-10-03 ## [v1.0.3](https://codeberg.org/scip/tablizer/tree/v1.0.3) - 2022-10-03
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.2...v1.0.3) [Full Changelog](https://codeberg.org/scip/tablizer/compare/v1.0.2...v1.0.3)
### Added ### Added
@@ -237,9 +237,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
## [v1.0.2](https://github.com/TLINDEN/tablizer/tree/v1.0.2) - 2022-10-02 ## [v1.0.2](https://codeberg.org/scip/tablizer/tree/v1.0.2) - 2022-10-02
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.1...v1.0.2) [Full Changelog](https://codeberg.org/scip/tablizer/compare/v1.0.1...v1.0.2)
### Added ### Added
@@ -255,9 +255,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
## [v1.0.1](https://github.com/TLINDEN/tablizer/tree/v1.0.1) - 2022-09-30 ## [v1.0.1](https://codeberg.org/scip/tablizer/tree/v1.0.1) - 2022-09-30
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.0...v1.0.1) [Full Changelog](https://codeberg.org/scip/tablizer/compare/v1.0.0...v1.0.1)
### Added ### Added
@@ -271,8 +271,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
## [v1.0.0](https://github.com/TLINDEN/tablizer/tree/v1.0.0) - 2022-09-28 ## [v1.0.0](https://codeberg.org/scip/tablizer/tree/v1.0.0) - 2022-09-28
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/02a64a5c3fe4220df2c791ff1421d16ebd428c19...v1.0.0) [Full Changelog](https://codeberg.org/scip/tablizer/compare/02a64a5c3fe4220df2c791ff1421d16ebd428c19...v1.0.0)
Initial release. Initial release.

View File

@@ -50,7 +50,7 @@ ifdef HAVE_POD
endif endif
buildlocal: buildlocal:
go build -ldflags "-X 'github.com/tlinden/tablizer/cfg.VERSION=$(VERSION)'" go build -ldflags "-X 'codeberg.org/scip/tablizer/cfg.VERSION=$(VERSION)'"
release: release:
gh release create $(version) --generate-notes gh release create $(version) --generate-notes
@@ -69,7 +69,7 @@ test: clean
singletest: singletest:
@echo "Call like this: 'make singletest TEST=TestPrepareColumns MOD=lib'" @echo "Call like this: 'make singletest TEST=TestPrepareColumns MOD=lib'"
go test -run $(TEST) github.com/tlinden/tablizer/$(MOD) $(OPTS) go test -run $(TEST) codeberg.org/scip/tablizer/$(MOD) $(OPTS)
cover-report: cover-report:
go test ./... -cover -coverprofile=coverage.out go test ./... -cover -coverprofile=coverage.out

20
Makefile.dist Normal file
View File

@@ -0,0 +1,20 @@
# -*-make-*-
.PHONY: install all
tool = rpn
PREFIX = /usr/local
UID = root
GID = 0
all:
@echo "Type 'sudo make install' to install the tool."
@echo "To change prefix, type 'sudo make install PREFIX=/opt'"
install:
install -d -o $(UID) -g $(GID) $(PREFIX)/bin
install -d -o $(UID) -g $(GID) $(PREFIX)/man/man1
install -d -o $(UID) -g $(GID) $(PREFIX)/share/doc
install -o $(UID) -g $(GID) -m 555 $(tool) $(PREFIX)/sbin/
install -o $(UID) -g $(GID) -m 444 $(tool).1 $(PREFIX)/man/man1/
install -o $(UID) -g $(GID) -m 444 *.md $(PREFIX)/share/doc/

View File

@@ -1,6 +1,6 @@
[![Actions](https://github.com/tlinden/tablizer/actions/workflows/ci.yaml/badge.svg)](https://github.com/tlinden/tablizer/actions) [![status-badge](https://ci.codeberg.org/api/badges/15519/status.svg)](https://ci.codeberg.org/repos/15519)
[![License](https://img.shields.io/badge/license-GPL-blue.svg)](https://github.com/tlinden/tablizer/blob/master/LICENSE) [![License](https://img.shields.io/badge/license-GPL-blue.svg)](https://codeberg.org/scip/tablizer/blob/master/LICENSE)
[![Go Report Card](https://goreportcard.com/badge/github.com/tlinden/tablizer)](https://goreportcard.com/report/github.com/tlinden/tablizer) [![Go Report Card](https://goreportcard.com/badge/codeberg.org/scip/tablizer)](https://goreportcard.com/report/codeberg.org/scip/tablizer)
## tablizer - Manipulate tabular output of other programs ## tablizer - Manipulate tabular output of other programs
@@ -45,17 +45,17 @@ Operational Flags:
-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 (maybe char, string or :class:)
-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
-K --regex-colorizer /from/color/ colorize pattern of output (color: fg[:bg])
-j, --json Read JSON input (must be array of hashes) -j, --json Read JSON input (must be array of hashes)
-I, --interactive Interactively filter and select rows -I, --interactive Interactively filter and select rows
--auto-headers Generate headers if there are none present in input -g, --auto-headers Generate headers if there are none present in input
--custom-headers a,b,... Use custom headers, separated by comma -x, --custom-headers a,b,... Use custom headers, separated by comma
Output Flags (mutually exclusive): Output Flags (mutually exclusive):
-X, --extended Enable extended output -X, --extended Enable extended output
@@ -63,12 +63,14 @@ Output Flags (mutually exclusive):
-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
-J, --jsonout Enable JSON 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
-P, --template <tpl> Enable template mode with template <tpl>
-L, --hightlight-lines Use alternating background colors for tables -L, --hightlight-lines Use alternating background colors for tables
-o, --ofs <char> Output field separator, used by -A and -C.
-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
@@ -176,7 +178,7 @@ 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 There's also an interactive mode, invoked with the option `-I`, where
you can interactively filter and select rows: 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" /> <img width="937" height="293" alt="interactive" src="https://github.com/user-attachments/assets/0d4d65e2-d156-43ed-8021-39047c7939ed" />
@@ -192,7 +194,7 @@ There are multiple ways to install **tablizer**:
stew install tlinden/tablizer stew install tlinden/tablizer
``` ```
- Go to the [latest release page](https://github.com/tlinden/tablizer/releases/latest), - Go to the [latest release page](https://codeberg.org/scip/tablizer/releases),
locate the binary for your operating system and platform. locate the binary for your operating system and platform.
Download it and put it into some directory within your `$PATH` variable. Download it and put it into some directory within your `$PATH` variable.
@@ -205,7 +207,7 @@ There are multiple ways to install **tablizer**:
- You can also install from source. Issue the following commands in your shell: - You can also install from source. Issue the following commands in your shell:
``` ```
git clone https://github.com/TLINDEN/tablizer.git git clone https://codeberg.org/scip/tablizer.git
cd tablizer cd tablizer
make make
sudo make install sudo make install
@@ -219,7 +221,7 @@ hesitate to ask me about it, I'll add it.
The documentation is provided as a unix man-page. It will be The documentation is provided as a unix man-page. It will be
automatically installed if you install from source. automatically installed if you install from source.
[However, you can read the man-page online](https://github.com/TLINDEN/tablizer/blob/main/tablizer.pod). [However, you can read the man-page online](https://codeberg.org/scip/tablizer/raw/branch/main/tablizer.pod).
Or if you cloned the repository you can read it this way (perl needs Or if you cloned the repository you can read it this way (perl needs
to be installed though): `perldoc tablizer.pod`. to be installed though): `perldoc tablizer.pod`.
@@ -236,7 +238,7 @@ that's the best way for me to forget to do something.
In order to report a bug, unexpected behavior, feature requests In order to report a bug, unexpected behavior, feature requests
or to submit a patch, please open an issue on github: or to submit a patch, please open an issue on github:
https://github.com/TLINDEN/tablizer/issues. https://codeberg.org/scip/tablizer/issues.
## Prior Art ## Prior Art
@@ -283,4 +285,4 @@ T.v.Dein <tom AT vondein DOT org>
## Project homepage ## Project homepage
https://github.com/TLINDEN/tablizer https://codeberg.org/scip/tablizer

View File

@@ -1,5 +1,5 @@
/* /*
Copyright © 2022-2025 Thomas von Dein Copyright © 2022-2026 Thomas von Dein
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -28,7 +28,7 @@ import (
) )
const ( const (
Version = "v1.5.11" Version = "v1.6.0"
MAXPARTS = 2 MAXPARTS = 2
) )
@@ -95,21 +95,22 @@ type Config struct {
InputJSON bool InputJSON bool
AutoHeaders bool AutoHeaders bool
CustomHeaders []string CustomHeaders []string
Template string
SortMode string SortMode string
SortDescending bool SortDescending bool
SortByColumn string // 1,2 SortByColumn string // 1,2
UseSortByColumn []int // []int{1,2} UseSortByColumn []int // []int{1,2}
TransposeColumns string // 1,2 TransposeColumns string // 1,2
UseTransposeColumns []int // []int{1,2} UseTransposeColumns []int // []int{1,2}
Transposers []string // []string{"/ /-/", "/foo/bar/"}
UseTransposers []Transposer // {Search: re, Replace: string} Transposers []string // []string{"/ /-/", "/foo/bar/"}
UseTransposers []Transposer // {Search: re, Replace: string}
Colorizers []string // []string{"/ /-/", "/foo/fg[:bg]/"}
UseColorizers []Transposer // {Search: re, Replace: color}
/*
FIXME: make configurable somehow, config file or ENV
see https://github.com/gookit/color.
*/
ColorStyle color.Style ColorStyle color.Style
HighlightStyle color.Style HighlightStyle color.Style
NoHighlightStyle color.Style NoHighlightStyle color.Style
@@ -142,6 +143,7 @@ type Modeflag struct {
A bool A bool
C bool C bool
J bool J bool
P bool // template
} }
// used for switching printers // used for switching printers
@@ -154,6 +156,7 @@ const (
CSV CSV
ASCII ASCII
Json Json
Template
) )
// various sort types // various sort types
@@ -294,6 +297,8 @@ func (conf *Config) PrepareModeFlags(flag Modeflag) {
conf.OutputMode = CSV conf.OutputMode = CSV
case flag.J: case flag.J:
conf.OutputMode = Json conf.OutputMode = Json
case conf.Template != "":
conf.OutputMode = Template
default: default:
conf.OutputMode = ASCII conf.OutputMode = ASCII
} }
@@ -352,6 +357,23 @@ func (conf *Config) PrepareTransposers() error {
return nil return nil
} }
func (conf *Config) PrepareColorizers() error {
for _, colorizer := range conf.Colorizers {
parts := strings.Split(colorizer, string(colorizer[0]))
if len(parts) != 4 {
return fmt.Errorf("colorizer function must have the format /regexp/foreground-color[:background-color]/")
}
conf.UseColorizers = append(conf.UseColorizers,
Transposer{
Search: *regexp.MustCompile(parts[1]),
Replace: parts[2]},
)
}
return nil
}
func (conf *Config) CheckEnv() { func (conf *Config) CheckEnv() {
// check for environment vars, command line flags have precedence, // check for environment vars, command line flags have precedence,
// NO_COLOR is being checked by the color module itself. // NO_COLOR is being checked by the color module itself.

View File

@@ -39,7 +39,6 @@ func TestPrepareModeFlags(t *testing.T) {
{Modeflag{}, ASCII}, {Modeflag{}, ASCII},
} }
// FIXME: use a map for easier printing
for _, testdata := range tests { for _, testdata := range tests {
testname := fmt.Sprintf("PrepareModeFlags-expect-%d", testdata.expect) testname := fmt.Sprintf("PrepareModeFlags-expect-%d", testdata.expect)
t.Run(testname, func(t *testing.T) { t.Run(testname, func(t *testing.T) {

View File

@@ -1,5 +1,5 @@
/* /*
Copyright © 2022-2025 Thomas von Dein Copyright © 2022-2026 Thomas von Dein
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -23,9 +23,9 @@ import (
"slices" "slices"
"strings" "strings"
"codeberg.org/scip/tablizer/cfg"
"codeberg.org/scip/tablizer/lib"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/tlinden/tablizer/cfg"
"github.com/tlinden/tablizer/lib"
) )
func completion(cmd *cobra.Command, mode string) error { func completion(cmd *cobra.Command, mode string) error {
@@ -95,6 +95,7 @@ func Execute() {
conf.PrepareCustomHeaders(headers) conf.PrepareCustomHeaders(headers)
wrapE(conf.PrepareFilters()) wrapE(conf.PrepareFilters())
wrapE(conf.PrepareColorizers())
conf.DetermineColormode() conf.DetermineColormode()
conf.ApplyDefaults() conf.ApplyDefaults()
@@ -179,6 +180,8 @@ func Execute() {
"Enable ASCII output (default)") "Enable ASCII output (default)")
rootCmd.MarkFlagsMutuallyExclusive("extended", "markdown", "orgtbl", rootCmd.MarkFlagsMutuallyExclusive("extended", "markdown", "orgtbl",
"shell", "yaml", "csv") "shell", "yaml", "csv")
rootCmd.PersistentFlags().StringVarP(&conf.Template, "template", "P", "",
"template for template output mode")
// config file // config file
rootCmd.PersistentFlags().StringVarP(&conf.Configfile, "config", "f", cfg.DefaultConfigfile, rootCmd.PersistentFlags().StringVarP(&conf.Configfile, "config", "f", cfg.DefaultConfigfile,
@@ -189,6 +192,8 @@ func Execute() {
"filter", "F", nil, "Filter by field (field=regexp || field!=regexp)") "filter", "F", nil, "Filter by field (field=regexp || field!=regexp)")
rootCmd.PersistentFlags().StringArrayVarP(&conf.Transposers, rootCmd.PersistentFlags().StringArrayVarP(&conf.Transposers,
"regex-transposer", "R", nil, "apply /search/replace/ regexp to fields given in -T") "regex-transposer", "R", nil, "apply /search/replace/ regexp to fields given in -T")
rootCmd.PersistentFlags().StringArrayVarP(&conf.Colorizers,
"regex-colorizer", "K", nil, "apply /search/color[:background]/ to the whole output")
// input // input
rootCmd.PersistentFlags().StringVarP(&conf.InputFile, "read-file", "r", "", rootCmd.PersistentFlags().StringVarP(&conf.InputFile, "read-file", "r", "",

View File

@@ -1,7 +1,7 @@
package cmd package cmd
const shortusage = `tablizer [regex,...] [-r file] [flags] const shortusage = `tablizer [regex,...] [-r file] [flags]
-c col,... show specified columns -L highlight matching lines -c col,... show specified columns -L colorize rows
-k col,... sort by specified columns -j read JSON input -k col,... sort by specified columns -j read JSON input
-F col=reg filter field with regexp -v invert match -F col=reg filter field with regexp -v invert match
-T col,... transpose specified columns -n numberize columns -T col,... transpose specified columns -n numberize columns
@@ -13,6 +13,7 @@ const shortusage = `tablizer [regex,...] [-r file] [flags]
-x col,... use custom headers -d debug -x col,... use custom headers -d debug
-o char use char as output separator -g auto generate headers -o char use char as output separator -g auto generate headers
-O org -C CSV -M md -X ext -S shell -Y yaml -J json -D sort descending order -K /pattern/foreground[:background]/ colorize pattern of output
-m show manual --help show detailed help -v show version -O org -C CSV -M md -X ext -S shell -Y yaml -J json -P template
-a sort by age -i sort numerically -t sort by time` -a sort by age -i sort numerically -t sort by time -D sort descending order
-m show manual -v show version --help show detailed help`

View File

@@ -20,6 +20,7 @@ SYNOPSIS
-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
-K --regex-colorizer /from/color/ colorize pattern of output (color: fg[:bg])
-j, --json Read JSON input (must be array of hashes) -j, --json Read JSON input (must be array of hashes)
-I, --interactive Interactively filter and select rows -I, --interactive Interactively filter and select rows
-g, --auto-headers Generate headers if there are none present in input -g, --auto-headers Generate headers if there are none present in input
@@ -34,6 +35,7 @@ SYNOPSIS
-J, --jsonout Enable JSON output -J, --jsonout Enable JSON 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
-P, --template <tpl> Enable template mode with template <tpl>
-L, --hightlight-lines Use alternating background colors for tables -L, --hightlight-lines Use alternating background colors for tables
-o, --ofs <char> Output field separator, used by -A and -C. -o, --ofs <char> Output field separator, used by -A and -C.
-y, --yank-columns Yank specified columns (separated by ,) to clipboard, -y, --yank-columns Yank specified columns (separated by ,) to clipboard,
@@ -77,16 +79,16 @@ DESCRIPTION
use the -v option to exclude all rows which match the pattern. Hence: use the -v option to exclude all rows which match the pattern. Hence:
# read from STDIN # read from STDIN
kubectl get pods | tablizer > kubectl get pods | tablizer
# read a file # read a file
tablizer -r filename > tablizer -r filename
# search for pattern in a file (works like grep) # search for pattern in a file (works like grep)
tablizer regex -r 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. You can add the option -n, then The output looks like the original one. You can add the option -n, then
every header field will have a numer associated with it, e.g.: every header field will have a numer associated with it, e.g.:
@@ -96,18 +98,18 @@ DESCRIPTION
These numbers denote the column and you can use them to specify which These numbers denote the column and you can use them to specify which
columns you want to have in your output (see COLUMNS: columns you want to have in your output (see COLUMNS:
kubectl get pods | tablizer -c1,3 > kubectl get pods | tablizer -c1,3
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.
However, you may also just use the header names instead of numbers, eg: However, you may also just use the header names instead of numbers, eg:
kubectl get pods | tablizer -cname,status > kubectl get pods | tablizer -cname,status
You can also use regular expressions with -c, eg: You can also use regular expressions with -c, eg:
kubectl get pods | tablizer -c '[ae]' > 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
@@ -218,7 +220,7 @@ DESCRIPTION
Example for a case insensitive search: Example for a case insensitive search:
kubectl get pods -A | tablizer "/account/i" > kubectl get pods -A | tablizer "/account/i"
If you use the "!" flag, then the regex match will be negated, that is, If you use the "!" flag, then the regex match will be negated, that is,
if a line in the input matches the given regex, but "!" is supplied, if a line in the input matches the given regex, but "!" is supplied,
@@ -284,7 +286,7 @@ DESCRIPTION
We want to see only the CMD column and use a regex for this: We want to see only the CMD column and use a regex for this:
ps | tablizer -s '\s+' -c C > ps | tablizer -s '\s+' -c C
CMD(4) CMD(4)
bash bash
ps ps
@@ -315,7 +317,7 @@ DESCRIPTION
Example: Example:
cat t/testtable2 > cat t/testtable2
NAME DURATION NAME DURATION
x 10 x 10
a 100 a 100
@@ -323,7 +325,7 @@ DESCRIPTION
u 4 u 4
k 6 k 6
cat t/testtable2 | tablizer -T2 -R '/^\d/4/' -n > cat t/testtable2 | tablizer -T2 -R '/^\d/4/' -n
NAME DURATION NAME DURATION
x 40 x 40
a 400 a 400
@@ -339,7 +341,7 @@ DESCRIPTION
header left, value right, aligned by the field widths. Here's an header left, value right, aligned by the field widths. Here's an
example: example:
kubectl get pods | ./tablizer -o extended > kubectl get pods | ./tablizer -o extended
NAME: repldepl-7bcd8d5b64-7zq4l NAME: repldepl-7bcd8d5b64-7zq4l
READY: 1/1 READY: 1/1
STATUS: Running STATUS: Running
@@ -352,7 +354,7 @@ DESCRIPTION
The option -o shell can be used if the output has to be processed by the 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: shell, it prints variable assignments for each cell, one line per row:
kubectl get pods | ./tablizer -o extended ./tablizer -o shell > 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-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-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" NAME="repldepl-7bcd8d5b64-q2bf4" READY="1/1" STATUS="Running" RESTARTS="9 (47m ago)" AGE="4d23h"
@@ -364,6 +366,18 @@ DESCRIPTION
markdown which prints a Markdown table, yaml, which prints yaml encoding markdown which prints a Markdown table, yaml, which prints yaml encoding
and CSV mode, which prints a comma separated value file. and CSV mode, which prints a comma separated value file.
A special output mode ist the Template mode, activated with the option
"--template". Template language is the Golang template language:
<https://pkg.go.dev/text/template>. You can also use lot's of additional
functions from: <https://masterminds.github.io/sprig/>. Here's an
example:
> kubectl get pods | tablizer --template "{{.name}} is {{.status}}"
alertmanager-kube-prometheus-alertmanager-0 is Running
grafana-fcc54cbc9-bk7s8 is Running
You can use header names as variables.
PUT FIELDS TO CLIPBOARD PUT FIELDS TO CLIPBOARD
You can let tablizer put fields to the clipboard using the option "-y". 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 This best fits the use-case when the result of your filtering yields
@@ -454,9 +468,20 @@ CONFIGURATION AND COLORS
lightGreen, lightMagenta, lightRed, lightWhite, lightYellow, magenta, lightGreen, lightMagenta, lightRed, lightWhite, lightYellow, magenta,
red, white, yellow red, white, yellow
The Variables FG and BG are being used to highlight matches. The other but you may also use HTML color codes without the hash sign.
*FG and *BG variables are for colored table output (enabled with the
"-L" parameter). The Variables FG and BG are being used to highlight matching rows. The
other *FG and *BG variables are for colored table output (enabled with
the "-L" parameter).
You can also use the option "-K" to colorize particular patterns, not
whole lines. The option can be given multiple times and expects the
following parameter:
-K '/regex/foreground[:background]/
that is, background color is optional. This colorization will applied on
top of any previous colorizations, if any.
Colorization can be turned off completely either by setting the Colorization can be turned off completely either by setting the
parameter "-N" or the environment variable NO_COLOR to a true value. parameter "-N" or the environment variable NO_COLOR to a true value.
@@ -464,7 +489,7 @@ CONFIGURATION AND COLORS
BUGS BUGS
In order to report a bug, unexpected behavior, feature requests or to In order to report a bug, unexpected behavior, feature requests or to
submit a patch, please open an issue on github: submit a patch, please open an issue on github:
<https://github.com/TLINDEN/tablizer/issues>. <https://codeberg.org/scip/tablizer/issues>.
LICENSE LICENSE
This software is licensed under the GNU GENERAL PUBLIC LICENSE version This software is licensed under the GNU GENERAL PUBLIC LICENSE version
@@ -518,6 +543,7 @@ Operational Flags:
-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
-K --regex-colorizer /from/color/ colorize pattern of output (color: fg[:bg])
-j, --json Read JSON input (must be array of hashes) -j, --json Read JSON input (must be array of hashes)
-I, --interactive Interactively filter and select rows -I, --interactive Interactively filter and select rows
-g, --auto-headers Generate headers if there are none present in input -g, --auto-headers Generate headers if there are none present in input
@@ -532,6 +558,7 @@ Output Flags (mutually exclusive):
-J, --jsonout Enable JSON output -J, --jsonout Enable JSON 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
-P, --template <tpl> Enable template mode with template <tpl>
-L, --hightlight-lines Use alternating background colors for tables -L, --hightlight-lines Use alternating background colors for tables
-o, --ofs <char> Output field separator, used by -A and -C. -o, --ofs <char> Output field separator, used by -A and -C.
-y, --yank-columns Yank specified columns (separated by ,) to clipboard, -y, --yank-columns Yank specified columns (separated by ,) to clipboard,

13
go.mod
View File

@@ -1,4 +1,4 @@
module github.com/tlinden/tablizer module codeberg.org/scip/tablizer
go 1.24.0 go 1.24.0
@@ -22,6 +22,10 @@ require (
) )
require ( require (
dario.cat/mergo v1.0.1 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.3.0 // indirect
github.com/Masterminds/sprig/v3 v3.3.0 // indirect
github.com/agext/levenshtein v1.2.3 // indirect github.com/agext/levenshtein v1.2.3 // indirect
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
github.com/atotto/clipboard v0.1.4 // indirect github.com/atotto/clipboard v0.1.4 // indirect
@@ -34,12 +38,16 @@ require (
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
github.com/fatih/color v1.18.0 // indirect github.com/fatih/color v1.18.0 // indirect
github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-cmp v0.6.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/huandu/xstrings v1.5.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-localereader v0.0.1 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/reflow v0.3.0 // indirect github.com/muesli/reflow v0.3.0 // indirect
@@ -49,9 +57,12 @@ require (
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect github.com/rivo/uniseg v0.4.7 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
github.com/spf13/cast v1.7.0 // indirect
github.com/spf13/pflag v1.0.9 // indirect github.com/spf13/pflag v1.0.9 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
github.com/zclconf/go-cty v1.16.3 // indirect github.com/zclconf/go-cty v1.16.3 // indirect
golang.org/x/crypto v0.38.0 // indirect
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
golang.org/x/mod v0.21.0 // indirect golang.org/x/mod v0.21.0 // indirect
golang.org/x/sync v0.15.0 // indirect golang.org/x/sync v0.15.0 // indirect

22
go.sum
View File

@@ -1,3 +1,11 @@
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0=
github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs=
github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0=
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs= github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs=
@@ -38,12 +46,16 @@ github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gookit/assert v0.1.1 h1:lh3GcawXe/p+cU7ESTZ5Ui3Sm/x8JWpIis4/1aF0mY0= github.com/gookit/assert v0.1.1 h1:lh3GcawXe/p+cU7ESTZ5Ui3Sm/x8JWpIis4/1aF0mY0=
github.com/gookit/assert v0.1.1/go.mod h1:jS5bmIVQZTIwk42uXl4lyj4iaaxx32tqH16CFj0VX2E= github.com/gookit/assert v0.1.1/go.mod h1:jS5bmIVQZTIwk42uXl4lyj4iaaxx32tqH16CFj0VX2E=
github.com/gookit/color v1.6.0 h1:JjJXBTk1ETNyqyilJhkTXJYYigHG24TM9Xa2M1xAhRA= github.com/gookit/color v1.6.0 h1:JjJXBTk1ETNyqyilJhkTXJYYigHG24TM9Xa2M1xAhRA=
github.com/gookit/color v1.6.0/go.mod h1:9ACFc7/1IpHGBW8RwuDm/0YEnhg3dwwXpoMsmtyHfjs= github.com/gookit/color v1.6.0/go.mod h1:9ACFc7/1IpHGBW8RwuDm/0YEnhg3dwwXpoMsmtyHfjs=
github.com/hashicorp/hcl/v2 v2.24.0 h1:2QJdZ454DSsYGoaE6QheQZjtKZSUs9Nh2izTWiwQxvE= github.com/hashicorp/hcl/v2 v2.24.0 h1:2QJdZ454DSsYGoaE6QheQZjtKZSUs9Nh2izTWiwQxvE=
github.com/hashicorp/hcl/v2 v2.24.0/go.mod h1:oGoO1FIQYfn/AgyOhlg9qLC6/nOJPX3qGbkZpYAcqfM= github.com/hashicorp/hcl/v2 v2.24.0/go.mod h1:oGoO1FIQYfn/AgyOhlg9qLC6/nOJPX3qGbkZpYAcqfM=
github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI=
github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4= github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4=
@@ -60,8 +72,12 @@ github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRC
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
@@ -88,6 +104,10 @@ github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0t
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg= github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg=
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w=
github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
@@ -107,6 +127,8 @@ github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6
github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM= github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=

View File

@@ -1,5 +1,5 @@
/* /*
Copyright © 2022-2025 Thomas von Dein Copyright © 2022-2026 Thomas von Dein
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -22,8 +22,8 @@ import (
"io" "io"
"strings" "strings"
"codeberg.org/scip/tablizer/cfg"
"github.com/lithammer/fuzzysearch/fuzzy" "github.com/lithammer/fuzzysearch/fuzzy"
"github.com/tlinden/tablizer/cfg"
) )
/* /*

View File

@@ -22,7 +22,7 @@ import (
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/tlinden/tablizer/cfg" "codeberg.org/scip/tablizer/cfg"
) )
func TestMatchPattern(t *testing.T) { func TestMatchPattern(t *testing.T) {

View File

@@ -1,5 +1,5 @@
/* /*
Copyright © 2022 Thomas von Dein Copyright © 2022-2026 Thomas von Dein
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -26,8 +26,8 @@ import (
"strconv" "strconv"
"strings" "strings"
"codeberg.org/scip/tablizer/cfg"
"github.com/gookit/color" "github.com/gookit/color"
"github.com/tlinden/tablizer/cfg"
) )
func findindex(s []int, e int) (int, bool) { func findindex(s []int, e int) (int, bool) {
@@ -245,35 +245,33 @@ func reduceColumns(conf cfg.Config, data *Tabdata) {
} }
} }
// FIXME: refactor this beast!
func colorizeData(conf cfg.Config, output string) string { func colorizeData(conf cfg.Config, output string) string {
if !conf.NoColor && !color.IsConsole(os.Stdout) {
return output
}
switch { switch {
case conf.UseHighlight && color.IsConsole(os.Stdout): case conf.UseHighlight:
highlight := true highlight := true
colorized := "" colorized := ""
first := true style := color.Style{}
for _, line := range strings.Split(output, "\n") { for idx, line := range strings.Split(output, "\n") {
if highlight { if idx == 0 {
if first { style = conf.HighlightHdrStyle
// we need to add two spaces to the header line
// because tablewriter omits them for some reason
// in pprint mode. This doesn't matter as long as
// we don't use colorization. But with colors the
// missing spaces can be seen.
if conf.OutputMode == cfg.ASCII {
line += " "
}
line = conf.HighlightHdrStyle.Sprint(line)
first = false
} else {
line = conf.HighlightStyle.Sprint(line)
}
} else {
line = conf.NoHighlightStyle.Sprint(line)
} }
switch highlight {
case true:
if idx > 0 {
style = conf.HighlightStyle
}
case false:
style = conf.NoHighlightStyle
}
line = style.Sprint(line)
highlight = !highlight highlight = !highlight
colorized += line + "\n" colorized += line + "\n"
@@ -281,7 +279,7 @@ func colorizeData(conf cfg.Config, output string) string {
return colorized return colorized
case len(conf.Patterns) > 0 && !conf.NoColor && color.IsConsole(os.Stdout): case len(conf.Patterns) > 0:
out := output out := output
for _, re := range conf.Patterns { for _, re := range conf.Patterns {

View File

@@ -23,7 +23,7 @@ import (
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/tlinden/tablizer/cfg" "codeberg.org/scip/tablizer/cfg"
) )
func TestContains(t *testing.T) { func TestContains(t *testing.T) {

View File

@@ -23,7 +23,7 @@ import (
"io" "io"
"os" "os"
"github.com/tlinden/tablizer/cfg" "codeberg.org/scip/tablizer/cfg"
) )
const RWRR = 0755 const RWRR = 0755

View File

@@ -30,7 +30,7 @@ import (
"strings" "strings"
"github.com/alecthomas/repr" "github.com/alecthomas/repr"
"github.com/tlinden/tablizer/cfg" "codeberg.org/scip/tablizer/cfg"
) )
/* /*

View File

@@ -24,7 +24,7 @@ import (
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/tlinden/tablizer/cfg" "codeberg.org/scip/tablizer/cfg"
) )
var input = []struct { var input = []struct {

View File

@@ -1,5 +1,5 @@
/* /*
Copyright © 2022-2025 Thomas von Dein Copyright © 2022-2026 Thomas von Dein
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -23,14 +23,17 @@ import (
"fmt" "fmt"
"io" "io"
"log" "log"
"os"
"strconv" "strconv"
"strings" "strings"
"text/template"
"codeberg.org/scip/tablizer/cfg"
"github.com/Masterminds/sprig/v3"
"github.com/gookit/color" "github.com/gookit/color"
"github.com/olekukonko/tablewriter" "github.com/olekukonko/tablewriter"
"github.com/olekukonko/tablewriter/renderer" "github.com/olekukonko/tablewriter/renderer"
"github.com/olekukonko/tablewriter/tw" "github.com/olekukonko/tablewriter/tw"
"github.com/tlinden/tablizer/cfg"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
@@ -66,13 +69,18 @@ func printData(writer io.Writer, conf cfg.Config, data *Tabdata) {
printJsonData(writer, data) printJsonData(writer, data)
case cfg.CSV: case cfg.CSV:
printCSVData(writer, conf, data) printCSVData(writer, conf, data)
case cfg.Template:
printTemplateData(writer, conf, data)
default: default:
printASCIIData(writer, conf, data) printASCIIData(writer, conf, data)
} }
} }
func output(writer io.Writer, str string) { func output(writer io.Writer, conf cfg.Config, str string) {
fmt.Fprint(writer, str) _, err := fmt.Fprint(writer, colorizeOutput(conf, str))
if err != nil {
log.Fatalf("failed to print output: %s", err)
}
} }
/* /*
@@ -131,7 +139,7 @@ func printOrgmodeData(writer io.Writer, conf cfg.Config, data *Tabdata) {
log.Fatalf("Failed to render table: %s", err) log.Fatalf("Failed to render table: %s", err)
} }
output(writer, color.Sprint(colorizeData(conf, tableString.String()))) output(writer, conf, color.Sprint(colorizeData(conf, tableString.String())))
} }
/* /*
@@ -190,7 +198,7 @@ func printMarkdownData(writer io.Writer, conf cfg.Config, data *Tabdata) {
log.Fatalf("Failed to render table: %s", err) log.Fatalf("Failed to render table: %s", err)
} }
output(writer, color.Sprint(colorizeData(conf, tableString.String()))) output(writer, conf, color.Sprint(colorizeData(conf, tableString.String())))
} }
/* /*
@@ -247,7 +255,7 @@ func printASCIIData(writer io.Writer, conf cfg.Config, data *Tabdata) {
log.Fatalf("Failed to render table: %s", err) log.Fatalf("Failed to render table: %s", err)
} }
output(writer, color.Sprint(colorizeData(conf, tableString.String()))) output(writer, conf, color.Sprint(colorizeData(conf, tableString.String())))
} }
/* /*
@@ -268,7 +276,7 @@ func printExtendedData(writer io.Writer, conf cfg.Config, data *Tabdata) {
} }
} }
output(writer, colorizeData(conf, out)) output(writer, conf, colorizeData(conf, out))
} }
/* /*
@@ -291,7 +299,7 @@ func printShellData(writer io.Writer, data *Tabdata) {
} }
// no colorization here // no colorization here
output(writer, out) output(writer, cfg.Config{}, out)
} }
func printJsonData(writer io.Writer, data *Tabdata) { func printJsonData(writer io.Writer, data *Tabdata) {
@@ -320,7 +328,7 @@ func printJsonData(writer io.Writer, data *Tabdata) {
log.Fatal(err) log.Fatal(err)
} }
output(writer, string(jsonstr)) output(writer, cfg.Config{}, string(jsonstr))
} }
func printYamlData(writer io.Writer, data *Tabdata) { func printYamlData(writer io.Writer, data *Tabdata) {
@@ -357,7 +365,7 @@ func printYamlData(writer io.Writer, data *Tabdata) {
log.Fatal(err) log.Fatal(err)
} }
output(writer, string(yamlstr)) output(writer, cfg.Config{}, string(yamlstr))
} }
func printCSVData(writer io.Writer, conf cfg.Config, data *Tabdata) { func printCSVData(writer io.Writer, conf cfg.Config, data *Tabdata) {
@@ -385,3 +393,45 @@ func printCSVData(writer io.Writer, conf cfg.Config, data *Tabdata) {
log.Fatal(err) log.Fatal(err)
} }
} }
func printTemplateData(writer io.Writer, conf cfg.Config, data *Tabdata) {
tmpl, err := template.New("printer").Funcs(sprig.TxtFuncMap()).Parse(conf.Template)
if err != nil {
log.Fatalf("failed to parse template: %s", err)
}
buf := strings.Builder{}
for line, dict := range data.ToMap() {
err = tmpl.Execute(&buf, dict)
if err != nil {
log.Fatalf("failed to execute template in line %d: %s", line, err)
}
buf.WriteString("\n")
}
if _, err := fmt.Fprintln(writer, buf.String()); err != nil {
log.Fatalf("failed to print output: %s", err)
}
}
func colorizeOutput(conf cfg.Config, input string) string {
if len(conf.UseColorizers) > 0 && !conf.NoColor && color.IsConsole(os.Stdout) {
for _, colorizer := range conf.UseColorizers {
// colorize matching parts of the whole output with given color, if the terminal supports it
// color may contain fg:bg or just fg. Color definitions see https://github.com/gookit/color
input = colorizer.Search.ReplaceAllStringFunc(input, func(in string) string {
col := colorizer.Replace
if strings.Contains(col, ":") {
parts := strings.Split(col, ":")
return color.Sprintf("<fg=%s;bg=%s>%s</>", parts[0], parts[1], in)
}
return color.Sprintf("<fg=%s>%s</>", col, in)
})
}
}
return input
}

View File

@@ -24,7 +24,7 @@ import (
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/tlinden/tablizer/cfg" "codeberg.org/scip/tablizer/cfg"
) )
func newData() Tabdata { func newData() Tabdata {

View File

@@ -23,8 +23,8 @@ import (
"sort" "sort"
"strconv" "strconv"
"codeberg.org/scip/tablizer/cfg"
"github.com/araddon/dateparse" "github.com/araddon/dateparse"
"github.com/tlinden/tablizer/cfg"
) )
func sortTable(conf cfg.Config, data *Tabdata) { func sortTable(conf cfg.Config, data *Tabdata) {
@@ -38,6 +38,12 @@ func sortTable(conf cfg.Config, data *Tabdata) {
return return
} }
for _, column := range conf.UseSortByColumn {
if column > len(data.headers) {
return
}
}
// actual sorting // actual sorting
sort.SliceStable(data.entries, func(i, j int) bool { sort.SliceStable(data.entries, func(i, j int) bool {
// holds the result of a sort of one column // holds the result of a sort of one column

View File

@@ -22,7 +22,7 @@ import (
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/tlinden/tablizer/cfg" "codeberg.org/scip/tablizer/cfg"
) )
func TestDuration2Seconds(t *testing.T) { func TestDuration2Seconds(t *testing.T) {

View File

@@ -1,5 +1,5 @@
/* /*
Copyright © 2022-2024 Thomas von Dein Copyright © 2022-2025 Thomas von Dein
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -17,6 +17,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package lib package lib
import (
"strconv"
"strings"
)
// contains a whole parsed table // contains a whole parsed table
type Tabdata struct { type Tabdata struct {
maxwidthHeader int // longest header maxwidthHeader int // longest header
@@ -34,3 +39,41 @@ func (data *Tabdata) CloneEmpty() Tabdata {
return newdata return newdata
} }
// convert our internal data to a list of maps
func (data *Tabdata) ToMap() []map[string]any {
dictlist := make([]map[string]any, len(data.entries))
headers := make([]string, len(data.headers))
for idx, header := range data.headers {
headers[idx] = strings.ToLower(header)
}
for line, row := range data.entries {
dict := make(map[string]any, len(data.headers))
for col, cell := range row {
n, ok := strconv.Atoi(cell)
if ok == nil {
dict[headers[col]] = n
continue
}
if strings.ToLower(cell) == "true" {
dict[headers[col]] = true
continue
}
if strings.ToLower(cell) == "false" {
dict[headers[col]] = false
continue
}
dict[headers[col]] = cell
}
dictlist[line] = dict
}
return dictlist
}

View File

@@ -26,7 +26,7 @@ import (
"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/mattn/go-isatty"
"github.com/tlinden/tablizer/cfg" "codeberg.org/scip/tablizer/cfg"
) )
// The context exists outside of the bubble loop, and is being used as // The context exists outside of the bubble loop, and is being used as

View File

@@ -22,7 +22,7 @@ import (
"strings" "strings"
"github.com/tiagomelo/go-clipboard/clipboard" "github.com/tiagomelo/go-clipboard/clipboard"
"github.com/tlinden/tablizer/cfg" "codeberg.org/scip/tablizer/cfg"
) )
func yankColumns(conf cfg.Config, data *Tabdata) { func yankColumns(conf cfg.Config, data *Tabdata) {

View File

@@ -24,7 +24,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/tiagomelo/go-clipboard/clipboard" "github.com/tiagomelo/go-clipboard/clipboard"
"github.com/tlinden/tablizer/cfg" "codeberg.org/scip/tablizer/cfg"
) )
var yanktests = []struct { var yanktests = []struct {

View File

@@ -20,7 +20,7 @@ package main
import ( import (
"os" "os"
"github.com/tlinden/tablizer/cmd" "codeberg.org/scip/tablizer/cmd"
) )
func main() { func main() {

View File

@@ -49,7 +49,7 @@ for D in $DIST; do
fi fi
set -x set -x
GOOS=${os} GOARCH=${arch} go build -tags osusergo,netgo -ldflags "-extldflags=-static -w -X 'github.com/tlinden/tablizer/cfg.VERSION=${version}'" --trimpath $pie -o ${binfile} GOOS=${os} GOARCH=${arch} go build -tags osusergo,netgo -ldflags "-extldflags=-static -w -X 'codeberg.org/scip/tablizer/cfg.VERSION=${version}'" --trimpath $pie -o ${binfile}
strip --strip-all ${binfile} strip --strip-all ${binfile}
mkdir -p ${tardir} mkdir -p ${tardir}
cp ${binfile} README.md LICENSE ${tardir}/ cp ${binfile} README.md LICENSE ${tardir}/

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

16
t/test-template.txtar Normal file
View File

@@ -0,0 +1,16 @@
exec tablizer -r testtable.txt -P '{{.species | title}}s are {{.type }}'
stdout 'Humans are invasive'
exec tablizer -r testtable.txt -P '{{.species | sha256sum}}'
stdout '79a5478768d2447431a90f7f4549df735f50ad541371464c248abc7522dc3a01'
exec tablizer -r testtable.txt -P '{{add 100 .count}}'
stdout 104
-- testtable.txt --
SPECIES TYPE HOME COUNT STAGE
human invasive earth 4 brink
riedl peaceful keauna 33 civilized
namak invasive namak 123 imperium
heduu peaceful iu 66 imperium
kenaha peaceful kohi 3333 hunter-gatherer

5
t/testtable6.csv Normal file
View File

@@ -0,0 +1,5 @@
Date,Account Number,Subject,Amount
20250101,968723487,Dogs Medication Invoice 9919292,-450.00
20250103,172747812,Tax return tax id HHD813D/12564H,+912.14
20250105,987122711,Car repair order 020123,-299.45
20250108,731217273,Rent - 12234 Sunset Blvd,-2960.00
1 Date Account Number Subject Amount
2 20250101 968723487 Dogs Medication Invoice 9919292 -450.00
3 20250103 172747812 Tax return tax id HHD813D/12564H +912.14
4 20250105 987122711 Car repair order 020123 -299.45
5 20250108 731217273 Rent - 12234 Sunset Blvd -2960.00

View File

@@ -133,7 +133,7 @@
.\" ======================================================================== .\" ========================================================================
.\" .\"
.IX Title "TABLIZER 1" .IX Title "TABLIZER 1"
.TH TABLIZER 1 "2025-10-13" "1" "User Commands" .TH TABLIZER 1 "2026-01-19" "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
@@ -158,6 +158,7 @@ tablizer \- Manipulate tabular output of other programs
\& \-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
\& \-K \-\-regex\-colorizer /from/color/ colorize pattern of output (color: fg[:bg])
\& \-j, \-\-json Read JSON input (must be array of hashes) \& \-j, \-\-json Read JSON input (must be array of hashes)
\& \-I, \-\-interactive Interactively filter and select rows \& \-I, \-\-interactive Interactively filter and select rows
\& \-g, \-\-auto\-headers Generate headers if there are none present in input \& \-g, \-\-auto\-headers Generate headers if there are none present in input
@@ -172,6 +173,7 @@ tablizer \- Manipulate tabular output of other programs
\& \-J, \-\-jsonout Enable JSON output \& \-J, \-\-jsonout Enable JSON 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
\& \-P, \-\-template <tpl> Enable template mode with template <tpl>
\& \-L, \-\-hightlight\-lines Use alternating background colors for tables \& \-L, \-\-hightlight\-lines Use alternating background colors for tables
\& \-o, \-\-ofs <char> Output field separator, used by \-A and \-C. \& \-o, \-\-ofs <char> Output field separator, used by \-A and \-C.
\& \-y, \-\-yank\-columns Yank specified columns (separated by ,) to clipboard, \& \-y, \-\-yank\-columns Yank specified columns (separated by ,) to clipboard,
@@ -219,16 +221,16 @@ pattern. Hence:
.PP .PP
.Vb 2 .Vb 2
\& # read from STDIN \& # read from STDIN
\& kubectl get pods | tablizer \& > kubectl get pods | tablizer
\& \&
\& # read a file \& # read a file
\& tablizer \-r filename \& > tablizer \-r filename
\& \&
\& # search for pattern in a file (works like grep) \& # search for pattern in a file (works like grep)
\& tablizer regex \-r 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. You can add the option \fB\-n\fR, The output looks like the original one. You can add the option \fB\-n\fR,
@@ -242,7 +244,7 @@ These numbers denote the column and you can use them to specify which
columns you want to have in your output (see \s-1COLUMNS\s0: columns you want to have in your output (see \s-1COLUMNS\s0:
.PP .PP
.Vb 1 .Vb 1
\& kubectl get pods | tablizer \-c1,3 \& > kubectl get pods | tablizer \-c1,3
.Ve .Ve
.PP .PP
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
@@ -252,13 +254,13 @@ However, you may also just use the header names instead of numbers,
eg: eg:
.PP .PP
.Vb 1 .Vb 1
\& kubectl get pods | tablizer \-cname,status \& > kubectl get pods | tablizer \-cname,status
.Ve .Ve
.PP .PP
You can also use regular expressions with \fB\-c\fR, eg: You can also use regular expressions with \fB\-c\fR, eg:
.PP .PP
.Vb 1 .Vb 1
\& kubectl get pods | tablizer \-c \*(Aq[ae]\*(Aq \& > kubectl get pods | tablizer \-c \*(Aq[ae]\*(Aq
.Ve .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
@@ -381,7 +383,7 @@ and append the flag. The following flags are supported:
Example for a case insensitive search: Example for a case insensitive search:
.PP .PP
.Vb 1 .Vb 1
\& kubectl get pods \-A | tablizer "/account/i" \& > kubectl get pods \-A | tablizer "/account/i"
.Ve .Ve
.PP .PP
If you use the \f(CW\*(C`!\*(C'\fR flag, then the regex match will be negated, that If you use the \f(CW\*(C`!\*(C'\fR flag, then the regex match will be negated, that
@@ -460,7 +462,7 @@ Lets take this table:
We want to see only the \s-1CMD\s0 column and use a regex for this: We want to see only the \s-1CMD\s0 column and use a regex for this:
.PP .PP
.Vb 6 .Vb 6
\& ps | tablizer \-s \*(Aq\es+\*(Aq \-c C \& > ps | tablizer \-s \*(Aq\es+\*(Aq \-c C
\& CMD(4) \& CMD(4)
\& bash \& bash
\& ps \& ps
@@ -497,7 +499,7 @@ use a regexp containing the \f(CW\*(C`/\*(C'\fR character, eg:
Example: Example:
.PP .PP
.Vb 7 .Vb 7
\& cat t/testtable2 \& > cat t/testtable2
\& NAME DURATION \& NAME DURATION
\& x 10 \& x 10
\& a 100 \& a 100
@@ -505,7 +507,7 @@ Example:
\& u 4 \& u 4
\& k 6 \& k 6
\& \&
\& cat t/testtable2 | tablizer \-T2 \-R \*(Aq/^\ed/4/\*(Aq \-n \& > cat t/testtable2 | tablizer \-T2 \-R \*(Aq/^\ed/4/\*(Aq \-n
\& NAME DURATION \& NAME DURATION
\& x 40 \& x 40
\& a 400 \& a 400
@@ -523,7 +525,7 @@ printed vertically, header left, value right, aligned by the field
widths. Here's an example: widths. Here's an example:
.PP .PP
.Vb 6 .Vb 6
\& kubectl get pods | ./tablizer \-o extended \& > kubectl get pods | ./tablizer \-o extended
\& NAME: repldepl\-7bcd8d5b64\-7zq4l \& NAME: repldepl\-7bcd8d5b64\-7zq4l
\& READY: 1/1 \& READY: 1/1
\& STATUS: Running \& STATUS: Running
@@ -539,7 +541,7 @@ by the shell, it prints variable assignments for each cell, one line
per row: per row:
.PP .PP
.Vb 4 .Vb 4
\& kubectl get pods | ./tablizer \-o extended ./tablizer \-o shell \& > 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\-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\-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" \& NAME="repldepl\-7bcd8d5b64\-q2bf4" READY="1/1" STATUS="Running" RESTARTS="9 (47m ago)" AGE="4d23h"
@@ -550,8 +552,22 @@ You can use this in an eval loop.
Beside normal ascii mode (the default) and extended mode there are Beside normal ascii mode (the default) and extended mode there are
more output modes available: \fBorgtbl\fR which prints an Emacs org-mode more output modes available: \fBorgtbl\fR which prints an Emacs org-mode
table and \fBmarkdown\fR which prints a Markdown table, \fByaml\fR, which 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 prints yaml encoding and \fB\s-1CSV\s0\fR mode, which prints a comma separated
value file. value file.
.PP
A special output mode ist the \fBTemplate\fR mode, activated with the
option \f(CW\*(C`\-\-template\*(C'\fR. Template language is the Golang template
language: <https://pkg.go.dev/text/template>. You can also use lot's
of additional functions from:
<https://masterminds.github.io/sprig/>. Here's an example:
.PP
.Vb 3
\& > kubectl get pods | tablizer \-\-template "{{.name}} is {{.status}}"
\& alertmanager\-kube\-prometheus\-alertmanager\-0 is Running
\& grafana\-fcc54cbc9\-bk7s8 is Running
.Ve
.PP
You can use header names as variables.
.SS "\s-1PUT FIELDS TO CLIPBOARD\s0" .SS "\s-1PUT FIELDS TO CLIPBOARD\s0"
.IX Subsection "PUT FIELDS TO CLIPBOARD" .IX Subsection "PUT FIELDS TO CLIPBOARD"
You can let tablizer put fields to the clipboard using the option You can let tablizer put fields to the clipboard using the option
@@ -667,9 +683,22 @@ black, blue, cyan, darkGray, default, green, lightBlue, lightCyan,
lightGreen, lightMagenta, lightRed, lightWhite, lightYellow, lightGreen, lightMagenta, lightRed, lightWhite, lightYellow,
magenta, red, white, yellow magenta, red, white, yellow
.PP .PP
The Variables \fB\s-1FG\s0\fR and \fB\s-1BG\s0\fR are being used to highlight matches. The but you may also use \s-1HTML\s0 color codes without the hash sign.
other *FG and *BG variables are for colored table output (enabled with .PP
the \f(CW\*(C`\-L\*(C'\fR parameter). The Variables \fB\s-1FG\s0\fR and \fB\s-1BG\s0\fR are being used to highlight matching
rows. The other *FG and *BG variables are for colored table output
(enabled with the \f(CW\*(C`\-L\*(C'\fR parameter).
.PP
You can also use the option \f(CW\*(C`\-K\*(C'\fR to colorize particular patterns, not
whole lines. The option can be given multiple times and expects the
following parameter:
.PP
.Vb 1
\& \-K \*(Aq/regex/foreground[:background]/
.Ve
.PP
that is, background color is optional. This colorization will applied
on top of any previous colorizations, if any.
.PP .PP
Colorization can be turned off completely either by setting the Colorization can be turned off completely either by setting the
parameter \f(CW\*(C`\-N\*(C'\fR or the environment variable \fB\s-1NO_COLOR\s0\fR to a true value. parameter \f(CW\*(C`\-N\*(C'\fR or the environment variable \fB\s-1NO_COLOR\s0\fR to a true value.
@@ -677,7 +706,7 @@ parameter \f(CW\*(C`\-N\*(C'\fR or the environment variable \fB\s-1NO_COLOR\s0\f
.IX Header "BUGS" .IX Header "BUGS"
In order to report a bug, unexpected behavior, feature requests In order to report a bug, unexpected behavior, feature requests
or to submit a patch, please open an issue on github: or to submit a patch, please open an issue on github:
<https://github.com/TLINDEN/tablizer/issues>. <https://codeberg.org/scip/tablizer/issues>.
.SH "LICENSE" .SH "LICENSE"
.IX Header "LICENSE" .IX Header "LICENSE"
This software is licensed under the \s-1GNU GENERAL PUBLIC LICENSE\s0 version 3. This software is licensed under the \s-1GNU GENERAL PUBLIC LICENSE\s0 version 3.

View File

@@ -19,6 +19,7 @@ tablizer - Manipulate tabular output of other programs
-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
-K --regex-colorizer /from/color/ colorize pattern of output (color: fg[:bg])
-j, --json Read JSON input (must be array of hashes) -j, --json Read JSON input (must be array of hashes)
-I, --interactive Interactively filter and select rows -I, --interactive Interactively filter and select rows
-g, --auto-headers Generate headers if there are none present in input -g, --auto-headers Generate headers if there are none present in input
@@ -33,6 +34,7 @@ tablizer - Manipulate tabular output of other programs
-J, --jsonout Enable JSON output -J, --jsonout Enable JSON 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
-P, --template <tpl> Enable template mode with template <tpl>
-L, --hightlight-lines Use alternating background colors for tables -L, --hightlight-lines Use alternating background colors for tables
-o, --ofs <char> Output field separator, used by -A and -C. -o, --ofs <char> Output field separator, used by -A and -C.
-y, --yank-columns Yank specified columns (separated by ,) to clipboard, -y, --yank-columns Yank specified columns (separated by ,) to clipboard,
@@ -80,16 +82,16 @@ may also use the B<-v> option to exclude all rows which match the
pattern. Hence: pattern. Hence:
# read from STDIN # read from STDIN
kubectl get pods | tablizer > kubectl get pods | tablizer
# read a file # read a file
tablizer -r filename > tablizer -r filename
# search for pattern in a file (works like grep) # search for pattern in a file (works like grep)
tablizer regex -r 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. You can add the option B<-n>, The output looks like the original one. You can add the option B<-n>,
then every header field will have a numer associated with it, e.g.: then every header field will have a numer associated with it, e.g.:
@@ -99,7 +101,7 @@ then every header field will have a numer associated with it, e.g.:
These numbers denote the column and you can use them to specify which These numbers denote the column and you can use them to specify which
columns you want to have in your output (see L<COLUMNS>: columns you want to have in your output (see L<COLUMNS>:
kubectl get pods | tablizer -c1,3 > kubectl get pods | tablizer -c1,3
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.
@@ -107,11 +109,11 @@ the original order.
However, you may also just use the header names instead of numbers, However, you may also just use the header names instead of numbers,
eg: eg:
kubectl get pods | tablizer -cname,status > kubectl get pods | tablizer -cname,status
You can also use regular expressions with B<-c>, eg: You can also use regular expressions with B<-c>, eg:
kubectl get pods | tablizer -c '[ae]' > 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
@@ -236,7 +238,7 @@ and append the flag. The following flags are supported:
Example for a case insensitive search: Example for a case insensitive search:
kubectl get pods -A | tablizer "/account/i" > kubectl get pods -A | tablizer "/account/i"
If you use the C<!> flag, then the regex match will be negated, that If you use the C<!> flag, then the regex match will be negated, that
is, if a line in the input matches the given regex, but C<!> is is, if a line in the input matches the given regex, but C<!> is
@@ -307,7 +309,7 @@ Lets take this table:
We want to see only the CMD column and use a regex for this: We want to see only the CMD column and use a regex for this:
ps | tablizer -s '\s+' -c C > ps | tablizer -s '\s+' -c C
CMD(4) CMD(4)
bash bash
ps ps
@@ -340,7 +342,7 @@ use a regexp containing the C</> character, eg:
Example: Example:
cat t/testtable2 > cat t/testtable2
NAME DURATION NAME DURATION
x 10 x 10
a 100 a 100
@@ -348,7 +350,7 @@ Example:
u 4 u 4
k 6 k 6
cat t/testtable2 | tablizer -T2 -R '/^\d/4/' -n > cat t/testtable2 | tablizer -T2 -R '/^\d/4/' -n
NAME DURATION NAME DURATION
x 40 x 40
a 400 a 400
@@ -365,7 +367,7 @@ useful which enables I<extended mode>. In this mode, each row will be
printed vertically, header left, value right, aligned by the field printed vertically, header left, value right, aligned by the field
widths. Here's an example: widths. Here's an example:
kubectl get pods | ./tablizer -o extended > kubectl get pods | ./tablizer -o extended
NAME: repldepl-7bcd8d5b64-7zq4l NAME: repldepl-7bcd8d5b64-7zq4l
READY: 1/1 READY: 1/1
STATUS: Running STATUS: Running
@@ -379,7 +381,7 @@ The option B<-o shell> can be used if the output has to be processed
by the shell, it prints variable assignments for each cell, one line by the shell, it prints variable assignments for each cell, one line
per row: per row:
kubectl get pods | ./tablizer -o extended ./tablizer -o shell > 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-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-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" NAME="repldepl-7bcd8d5b64-q2bf4" READY="1/1" STATUS="Running" RESTARTS="9 (47m ago)" AGE="4d23h"
@@ -389,9 +391,22 @@ You can use this in an eval loop.
Beside normal ascii mode (the default) and extended mode there are Beside normal ascii mode (the default) and extended mode there are
more output modes available: B<orgtbl> which prints an Emacs org-mode more output modes available: B<orgtbl> which prints an Emacs org-mode
table and B<markdown> which prints a Markdown table, B<yaml>, which table and B<markdown> which prints a Markdown table, B<yaml>, which
prints yaml encoding and CSV mode, which prints a comma separated prints yaml encoding and B<CSV> mode, which prints a comma separated
value file. value file.
A special output mode ist the B<Template> mode, activated with the
option C<--template>. Template language is the Golang template
language: L<https://pkg.go.dev/text/template>. You can also use lot's
of additional functions from:
L<https://masterminds.github.io/sprig/>. Here's an example:
> kubectl get pods | tablizer --template "{{.name}} is {{.status}}"
alertmanager-kube-prometheus-alertmanager-0 is Running
grafana-fcc54cbc9-bk7s8 is Running
You can use header names as variables.
=head2 PUT FIELDS TO CLIPBOARD =head2 PUT FIELDS TO CLIPBOARD
You can let tablizer put fields to the clipboard using the option You can let tablizer put fields to the clipboard using the option
@@ -500,9 +515,20 @@ black, blue, cyan, darkGray, default, green, lightBlue, lightCyan,
lightGreen, lightMagenta, lightRed, lightWhite, lightYellow, lightGreen, lightMagenta, lightRed, lightWhite, lightYellow,
magenta, red, white, yellow magenta, red, white, yellow
The Variables B<FG> and B<BG> are being used to highlight matches. The but you may also use HTML color codes without the hash sign.
other *FG and *BG variables are for colored table output (enabled with
the C<-L> parameter). The Variables B<FG> and B<BG> are being used to highlight matching
rows. The other *FG and *BG variables are for colored table output
(enabled with the C<-L> parameter).
You can also use the option C<-K> to colorize particular patterns, not
whole lines. The option can be given multiple times and expects the
following parameter:
-K '/regex/foreground[:background]/
that is, background color is optional. This colorization will applied
on top of any previous colorizations, if any.
Colorization can be turned off completely either by setting the Colorization can be turned off completely either by setting the
parameter C<-N> or the environment variable B<NO_COLOR> to a true value. parameter C<-N> or the environment variable B<NO_COLOR> to a true value.
@@ -513,7 +539,7 @@ parameter C<-N> or the environment variable B<NO_COLOR> to a true value.
In order to report a bug, unexpected behavior, feature requests In order to report a bug, unexpected behavior, feature requests
or to submit a patch, please open an issue on github: or to submit a patch, please open an issue on github:
L<https://github.com/TLINDEN/tablizer/issues>. L<https://codeberg.org/scip/tablizer/issues>.
=head1 LICENSE =head1 LICENSE