Compare commits

...

10 Commits

Author SHA1 Message Date
80ec16a612 fix badge 2025-11-03 20:26:22 +01:00
fe600ffb66 catch io error 2025-11-03 20:22:32 +01:00
92d8017711 catch io error 2025-11-03 20:22:13 +01:00
5ca8b6c1cf moving to codeberg 2025-11-03 20:09:39 +01:00
bc717baa3f fix typo 2025-10-25 21:51:56 +02:00
c34f030914 add stew 2025-10-25 21:50:31 +02:00
T.v.Dein
f1aa9d0000 add json output mode (-J) (#87) 2025-10-14 07:18:30 +02:00
736dd37f16 fixed feature entry 2025-10-13 07:24:35 +02:00
e0dc6bb845 updated and added feature list 2025-10-13 07:23:54 +02:00
T.v.Dein
8bdb3db105 fix #85: add --auto-headers and --custom-headers (#86) 2025-10-10 13:08:16 +02:00
33 changed files with 454 additions and 461 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}}

69
.goreleaser.yaml Normal file
View File

@@ -0,0 +1,69 @@
# 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
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/epuppy/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]

32
.woodpecker/image.yaml Normal file
View File

@@ -0,0 +1,32 @@
# https://woodpecker-ci.org/plugins/docker-buildx
# enable Package unit and go to /scip/-/packages after building to link to proj
variables:
- &repo codeberg.org/${CI_REPO_OWNER}/TEMPLATE
steps:
dryrun:
image: docker.io/woodpeckerci/plugin-docker-buildx:latest
settings:
dockerfile: Dockerfile
platforms: linux/amd64
dry_run: true
repo: *repo
tags: latest
when:
event: [pull_request]
publish:
image: docker.io/woodpeckerci/plugin-docker-buildx:latest
settings:
dockerfile: Dockerfile
platforms: linux/amd64
repo: *repo
registry: codeberg.org
tags: latest,${CI_COMMIT_SHA:0:8},${CI_COMMIT_TAG}
username: ${CI_REPO_OWNER}
password:
from_secret: REGISTRY_TOKEN
when:
event: [tag]
branch: main

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

@@ -1,278 +0,0 @@
# Changelog
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).
## [v1.0.14](https://github.com/TLINDEN/tablizer/tree/v1.0.14) - 2023-01-23
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.13...v1.0.14)
### Fixed
- The -D parameter could not be used together with -a.
- Fixed invalid argv handling: when the user wanted to read from stdin
but gave an argument which was meant as a pattern, but also existed
as a filename, then tablizer opened the file, ignored stdin.
- Makefile indentation
### Added
- added licens notes about dependencies
- using hard coded uniseq version, see actions#3396457307
- updated dependencies (go module versions)
## [v1.0.13](https://github.com/TLINDEN/tablizer/tree/v1.0.13) - 2022-11-03
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.12...v1.0.13)
### Added
- Added command line flag to generate shell completion code
- Added an animated demo gif to the README to demonstrate the tool
### Fixed
- The `-A` flag wasn't implemented (default output mode).
- Fixed building from source on systems w/o perls pod tools,
which is not requrired anyway since I always commit the latest
manpage.
## [v1.0.12](https://github.com/TLINDEN/tablizer/tree/v1.0.12) - 2022-10-25
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.11...v1.0.12)
### Added
- Added support to parse CSV input
- Added CSV output support
- Added support for environment variables
### Changed
- We do not use the generated help message anymore, instead we use the
usage from the manpage, which we have to maintain anyway. It looks
better and has flag groups, which cobra is still lacking as of this
writing.
- More refactoring and re-organization, runtime configuration now
lives in the cfg module.
### Fixed
- Fixed [Bug #5](https://github.com/TLINDEN/tablizer/issues/5), where
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
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.10...v1.0.11)
### Added
- Added CI job golinter to regularly check for common mistakes.
- Added YAML output mode.
- Added more unit tests, we're over 95% in the lib module.
### Changed
- do not use any global variables anymore, makes the code easier to
maintain, understand and test
- using io.Writer in print* functions, which is easier to test, also
re-implemented the print tests.
- replaced go-str2duration with my own implementation `duration2int()`.
## [v1.0.10](https://github.com/TLINDEN/tablizer/tree/v1.0.10) - 2022-10-15
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.9...v1.0.10)
### Added
- Added various sort modes: sort by time, by duration, numerical (-a -t -i)
- Added possibility to modify sort order to descending (-D)
- Added support to specify a regexp in column selector -c, which can
also be mixed with numerical column spec
- More unit tests
### Fixed
- Column specification allowed to specify duplicate columns like `-c
1,2,1,2` unchecked. Now this list will be deduplicated before use.
## [v1.0.9](https://github.com/TLINDEN/tablizer/tree/v1.0.9) - 2022-10-14
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.8...v1.0.9)
### Added
- Added Changelog, Contribution guidelines and no COC.
### Changed
- some minor changes to satisfy linter.
## [v1.0.8](https://github.com/TLINDEN/tablizer/tree/v1.0.8) - 2022-10-13
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.7...v1.0.8)
### Added
- Added sort support with the new parameter -k (like sort(1)).
## [v1.0.7](https://github.com/TLINDEN/tablizer/tree/v1.0.7) - 2022-10-11
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.6...v1.0.7)
### Added
- Added pattern highlighting support.
- Added more unit tests.
### Fixed
- Fixed extended more output in combination with -c.
- Fixed issue #4, the version string was missing.
## [v1.0.6](https://github.com/TLINDEN/tablizer/tree/v1.0.6) - 2022-10-05
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.5...v1.0.6)
### Added
- Added documentation about regexp syntax in the manpage.
- Added more unit tests.
### Changed
- Rewrote the input parser.
- Some more refactoring work has been done.
## [v1.0.5](https://github.com/TLINDEN/tablizer/tree/v1.0.5) - 2022-10-05
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.4...v1.0.5)
### Added
- A new option has been added: --invert-match -v which behaves like
the same option in grep(1): it inverts the pattern match.
- A few more unit tests have been added.
### Fixed
- Pattern matching did not work, because the (new) help subcommand
lead to cobra taking care of the first arg to the program
(argv[1]). So now there's a new parameter -m which displays the
manpage and no more subcommands.
## [v1.0.4](https://github.com/TLINDEN/tablizer/tree/v1.0.4) - 2022-10-04
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.3...v1.0.4)
### Added
- Development version of the compiled binary now uses git vars
in addition to program version.
- Added an option to display the manual page (compiled in) as text:
--help, for cases where a user just installed the binary.
### Changed
- Fixed go module namespace.
## [v1.0.3](https://github.com/TLINDEN/tablizer/tree/v1.0.3) - 2022-10-03
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.2...v1.0.3)
### Added
- Added a new output mode: shell mode, which allows the user
to use the output in a shell eval loop to further process
the data.
### Changed
- More refactoring work has been done.
## [v1.0.2](https://github.com/TLINDEN/tablizer/tree/v1.0.2) - 2022-10-02
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.1...v1.0.2)
### Added
- Added some basic unit tests.
### Changed
- Code has been refactored to be more efficient.
- Replaced table generation code with Tablewriter.
## [v1.0.1](https://github.com/TLINDEN/tablizer/tree/v1.0.1) - 2022-09-30
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/v1.0.0...v1.0.1)
### Added
- Added a unix manual page.
- Added release builder to Makefile
### Changed
- Various minor fixes.
## [v1.0.0](https://github.com/TLINDEN/tablizer/tree/v1.0.0) - 2022-09-28
[Full Changelog](https://github.com/TLINDEN/tablizer/compare/02a64a5c3fe4220df2c791ff1421d16ebd428c19...v1.0.0)
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
@@ -11,6 +11,23 @@ ignore certain column[s] by regex, name or number. It can output the
tabular data in a range of formats (see below). There's even an tabular data in a range of formats (see below). There's even an
interactive filter/selection tool available. interactive filter/selection tool available.
## FEATURES
- supports csv, json or ascii format input from files or stdin
- split any tabular input data by character or regular expression into columns
- add headers if input data doesn't contain them (automatically or manually)
- print tabular data as ascii table, org-mode, markdown, csv, shell-evaluable or yaml format
- filter rows by regular expression (saves a call to `| grep ...`)
- filter rows by column filter
- filters may also be negations eg `-Fname!=cow.*` or `-v`
- modify cells wih regular expressions
- reduce columns by specifying which columns to show, with regex support
- color support
- sort by any field[s], multiple sort modes are supported
- shell completion for options
- regular used options can be put into a config file
- filter TUI where where you can interactively sort and filter rows
## Demo ## Demo
![demo cast](vhsdemo/demo.gif) ![demo cast](vhsdemo/demo.gif)
@@ -36,6 +53,9 @@ Operational Flags:
-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
-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
--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
@@ -167,7 +187,12 @@ you can interactively filter and select rows:
There are multiple ways to install **tablizer**: There are multiple ways to install **tablizer**:
- Go to the [latest release page](https://github.com/tlinden/tablizer/releases/latest), - You can use [stew](https://github.com/marwanhawari/stew) to install tablizer:
```default
stew install tlinden/tablizer
```
- 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.
@@ -180,7 +205,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
@@ -194,7 +219,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/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`.
@@ -211,7 +236,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
@@ -258,4 +283,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

@@ -28,7 +28,7 @@ import (
) )
const ( const (
Version = "v1.5.9" Version = "v1.5.11"
MAXPARTS = 2 MAXPARTS = 2
) )
@@ -93,6 +93,8 @@ type Config struct {
UseHighlight bool UseHighlight bool
Interactive bool Interactive bool
InputJSON bool InputJSON bool
AutoHeaders bool
CustomHeaders []string
SortMode string SortMode string
SortDescending bool SortDescending bool
@@ -139,6 +141,7 @@ type Modeflag struct {
Y bool Y bool
A bool A bool
C bool C bool
J bool
} }
// used for switching printers // used for switching printers
@@ -150,6 +153,7 @@ const (
Yaml Yaml
CSV CSV
ASCII ASCII
Json
) )
// various sort types // various sort types
@@ -288,6 +292,8 @@ func (conf *Config) PrepareModeFlags(flag Modeflag) {
conf.OutputMode = Yaml conf.OutputMode = Yaml
case flag.C: case flag.C:
conf.OutputMode = CSV conf.OutputMode = CSV
case flag.J:
conf.OutputMode = Json
default: default:
conf.OutputMode = ASCII conf.OutputMode = ASCII
} }
@@ -413,6 +419,12 @@ func (conf *Config) PreparePattern(patterns []*Pattern) error {
return nil return nil
} }
func (conf *Config) PrepareCustomHeaders(custom string) {
if len(custom) > 0 {
conf.CustomHeaders = strings.Split(custom, ",")
}
}
// Parse config file. Ignore if the file doesn't exist but return an // Parse config file. Ignore if the file doesn't exist but return an
// error if it exists but fails to read or parse // error if it exists but fails to read or parse
func (conf *Config) ParseConfigfile() error { func (conf *Config) ParseConfigfile() error {

View File

@@ -24,8 +24,8 @@ import (
"strings" "strings"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/tlinden/tablizer/cfg" "codeberg.org/scip/tablizer/cfg"
"github.com/tlinden/tablizer/lib" "codeberg.org/scip/tablizer/lib"
) )
func completion(cmd *cobra.Command, mode string) error { func completion(cmd *cobra.Command, mode string) error {
@@ -59,6 +59,7 @@ func Execute() {
ShowCompletion string ShowCompletion string
modeflag cfg.Modeflag modeflag cfg.Modeflag
sortmode cfg.Sortmode sortmode cfg.Sortmode
headers string
) )
var rootCmd = &cobra.Command{ var rootCmd = &cobra.Command{
@@ -91,6 +92,7 @@ func Execute() {
conf.CheckEnv() conf.CheckEnv()
conf.PrepareModeFlags(modeflag) conf.PrepareModeFlags(modeflag)
conf.PrepareSortFlags(sortmode) conf.PrepareSortFlags(sortmode)
conf.PrepareCustomHeaders(headers)
wrapE(conf.PrepareFilters()) wrapE(conf.PrepareFilters())
@@ -133,10 +135,14 @@ func Execute() {
"Transpose the speficied columns (separated by ,)") "Transpose the speficied columns (separated by ,)")
rootCmd.PersistentFlags().BoolVarP(&conf.Interactive, "interactive", "I", false, rootCmd.PersistentFlags().BoolVarP(&conf.Interactive, "interactive", "I", false,
"interactive mode") "interactive mode")
rootCmd.PersistentFlags().StringVarP(&conf.OFS, "ofs", "", "", rootCmd.PersistentFlags().StringVarP(&conf.OFS, "ofs", "o", "",
"Output field separator (' ' for ascii table, ',' for CSV)") "Output field separator (' ' for ascii table, ',' for CSV)")
rootCmd.PersistentFlags().BoolVarP(&conf.InputJSON, "json", "j", false, rootCmd.PersistentFlags().BoolVarP(&conf.InputJSON, "json", "j", false,
"JSON input mode") "JSON input mode")
rootCmd.PersistentFlags().BoolVarP(&conf.AutoHeaders, "auto-headers", "g", false,
"Generate headers automatically")
rootCmd.PersistentFlags().StringVarP(&headers, "custom-headers", "x", "",
"Custom headers")
// sort options // sort options
rootCmd.PersistentFlags().StringVarP(&conf.SortByColumn, "sort-by", "k", "", rootCmd.PersistentFlags().StringVarP(&conf.SortByColumn, "sort-by", "k", "",
@@ -165,6 +171,8 @@ func Execute() {
"Enable shell mode output") "Enable shell mode output")
rootCmd.PersistentFlags().BoolVarP(&modeflag.Y, "yaml", "Y", false, rootCmd.PersistentFlags().BoolVarP(&modeflag.Y, "yaml", "Y", false,
"Enable yaml output") "Enable yaml output")
rootCmd.PersistentFlags().BoolVarP(&modeflag.J, "jsonout", "J", false,
"Enable json output")
rootCmd.PersistentFlags().BoolVarP(&modeflag.C, "csv", "C", false, rootCmd.PersistentFlags().BoolVarP(&modeflag.C, "csv", "C", false,
"Enable CSV output") "Enable CSV output")
rootCmd.PersistentFlags().BoolVarP(&modeflag.A, "ascii", "A", false, rootCmd.PersistentFlags().BoolVarP(&modeflag.A, "ascii", "A", false,

View File

@@ -1,16 +1,18 @@
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 highlight matching lines
-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
-R /from/to/ apply replacement to columns in -T -N do not use colors -R /from/to/ apply replacement to columns in -T -N do not use colors
-y col,... yank columns to clipboard -H do not show headers -y col,... yank columns to clipboard -H do not show headers
--ofs char output field separator -s specify field separator --ofs char output field separator -s specify field separator
-r file read input from file -z use fuzzy search -r file read input from file -z use fuzzy search
-f file read config from file -I interactive filter mode -f file read config from file -I interactive filter mode
-d debug -x col,... use custom headers -d debug
-O org -C CSV -M md -X ext -S shell -Y yaml -D sort descending order -o char use char as output separator -g auto generate headers
-m show manual --help show detailed help -v show version
-a sort by age -i sort numerically -t sort by time` -O org -C CSV -M md -X ext -S shell -Y yaml -J json -D sort descending order
-m show manual --help show detailed help -v show version
-a sort by age -i sort numerically -t sort by time`

View File

@@ -22,6 +22,8 @@ SYNOPSIS
-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
-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
-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
@@ -29,12 +31,13 @@ SYNOPSIS
-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
-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
@@ -461,7 +464,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
@@ -517,6 +520,8 @@ Operational Flags:
-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
-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
-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
@@ -524,12 +529,13 @@ 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
-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

2
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

View File

@@ -23,7 +23,7 @@ import (
"strings" "strings"
"github.com/lithammer/fuzzysearch/fuzzy" "github.com/lithammer/fuzzysearch/fuzzy"
"github.com/tlinden/tablizer/cfg" "codeberg.org/scip/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

@@ -27,7 +27,7 @@ import (
"strings" "strings"
"github.com/gookit/color" "github.com/gookit/color"
"github.com/tlinden/tablizer/cfg" "codeberg.org/scip/tablizer/cfg"
) )
func findindex(s []int, e int) (int, bool) { func findindex(s []int, e int) (int, bool) {

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"
) )
/* /*
@@ -66,6 +66,43 @@ func Parse(conf cfg.Config, input io.Reader) (Tabdata, error) {
return data, err return data, err
} }
/*
* Setup headers, given headers might be usable headers or just the
* first row, which we use to determine how many headers to generate,
* if enabled.
*/
func SetHeaders(conf cfg.Config, headers []string) []string {
if !conf.AutoHeaders && len(conf.CustomHeaders) == 0 {
return headers
}
if conf.AutoHeaders {
heads := make([]string, len(headers))
for idx := range headers {
heads[idx] = fmt.Sprintf("%d", idx+1)
}
return heads
}
if len(conf.CustomHeaders) == len(headers) {
return conf.CustomHeaders
}
// use as much custom ones we have, generate the remainder
heads := make([]string, len(headers))
for idx := range headers {
if idx < len(conf.CustomHeaders) {
heads[idx] = conf.CustomHeaders[idx]
} else {
heads[idx] = fmt.Sprintf("%d", idx+1)
}
}
return heads
}
/* /*
Parse CSV input. Parse CSV input.
*/ */
@@ -87,7 +124,7 @@ func parseCSV(conf cfg.Config, input io.Reader) (Tabdata, error) {
} }
if len(records) >= 1 { if len(records) >= 1 {
data.headers = records[0] data.headers = SetHeaders(conf, records[0])
data.columns = len(records) data.columns = len(records)
for _, head := range data.headers { for _, head := range data.headers {
@@ -98,9 +135,14 @@ func parseCSV(conf cfg.Config, input io.Reader) (Tabdata, error) {
} }
} }
if len(records) > 1 { if len(records) >= 1 {
data.entries = records[1:] if conf.AutoHeaders || len(conf.CustomHeaders) > 0 {
data.entries = records
} else {
data.entries = records[1:]
}
} }
} }
return data, nil return data, nil
@@ -128,7 +170,9 @@ func parseTabular(conf cfg.Config, input io.Reader) (Tabdata, error) {
data.columns = len(parts) data.columns = len(parts)
// process all header fields // process all header fields
for _, part := range parts { firstrow := make([]string, len(parts))
for idx, part := range parts {
// register widest header field // register widest header field
headerlen := len(part) headerlen := len(part)
if headerlen > data.maxwidthHeader { if headerlen > data.maxwidthHeader {
@@ -136,11 +180,22 @@ func parseTabular(conf cfg.Config, input io.Reader) (Tabdata, error) {
} }
// register fields data // register fields data
data.headers = append(data.headers, strings.TrimSpace(part)) firstrow[idx] = strings.TrimSpace(part)
// done // done
hadFirst = true hadFirst = true
} }
data.headers = SetHeaders(conf, firstrow)
if conf.AutoHeaders || len(conf.CustomHeaders) > 0 {
// we do not use generated headers, consider as row
if matchPattern(conf, line) == conf.InvertMatch {
continue
}
data.entries = append(data.entries, firstrow)
}
} else { } else {
// data processing // data processing
if matchPattern(conf, line) == conf.InvertMatch { if matchPattern(conf, line) == conf.InvertMatch {

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 {
@@ -366,6 +366,56 @@ func TestParserSeparators(t *testing.T) {
} }
} }
func TestParserSetHeaders(t *testing.T) {
row := []string{"c", "b", "c", "d", "e"}
tests := []struct {
name string
custom []string
expect []string
auto bool
}{
{
name: "default",
expect: row,
},
{
name: "auto",
expect: strings.Split("1 2 3 4 5", " "),
auto: true,
},
{
name: "custom-complete",
custom: strings.Split("A B C D E", " "),
expect: strings.Split("A B C D E", " "),
},
{
name: "custom-too-short",
custom: strings.Split("A B", " "),
expect: strings.Split("A B 3 4 5", " "),
},
{
name: "custom-too-long",
custom: strings.Split("A B C D E F G", " "),
expect: strings.Split("A B C D E", " "),
},
}
for _, testdata := range tests {
testname := fmt.Sprintf("parse-%s", testdata.name)
t.Run(testname, func(t *testing.T) {
conf := cfg.Config{
AutoHeaders: testdata.auto,
CustomHeaders: testdata.custom,
}
headers := SetHeaders(conf, row)
assert.NotNil(t, headers)
assert.EqualValues(t, testdata.expect, headers)
})
}
}
func wrapValidateParser(conf cfg.Config, input io.Reader) (Tabdata, error) { func wrapValidateParser(conf cfg.Config, input io.Reader) (Tabdata, error) {
data, err := Parse(conf, input) data, err := Parse(conf, input)

View File

@@ -19,17 +19,18 @@ package lib
import ( import (
"encoding/csv" "encoding/csv"
"encoding/json"
"fmt" "fmt"
"io" "io"
"log" "log"
"strconv" "strconv"
"strings" "strings"
"codeberg.org/scip/tablizer/cfg"
"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"
) )
@@ -61,6 +62,8 @@ func printData(writer io.Writer, conf cfg.Config, data *Tabdata) {
printShellData(writer, data) printShellData(writer, data)
case cfg.Yaml: case cfg.Yaml:
printYamlData(writer, data) printYamlData(writer, data)
case cfg.Json:
printJsonData(writer, data)
case cfg.CSV: case cfg.CSV:
printCSVData(writer, conf, data) printCSVData(writer, conf, data)
default: default:
@@ -69,7 +72,10 @@ func printData(writer io.Writer, conf cfg.Config, data *Tabdata) {
} }
func output(writer io.Writer, str string) { func output(writer io.Writer, str string) {
fmt.Fprint(writer, str) _, err := fmt.Fprint(writer, str)
if err != nil {
log.Fatalf("failed to print output: %s", err)
}
} }
/* /*
@@ -291,6 +297,35 @@ func printShellData(writer io.Writer, data *Tabdata) {
output(writer, out) output(writer, out)
} }
func printJsonData(writer io.Writer, data *Tabdata) {
objlist := make([]map[string]any, len(data.entries))
if len(data.entries) > 0 {
for i, entry := range data.entries {
obj := make(map[string]any, len(entry))
for idx, value := range entry {
num, err := strconv.Atoi(value)
if err == nil {
obj[data.headers[idx]] = num
} else {
obj[data.headers[idx]] = value
}
}
objlist[i] = obj
}
}
jsonstr, err := json.MarshalIndent(&objlist, "", " ")
if err != nil {
log.Fatal(err)
}
output(writer, string(jsonstr))
}
func printYamlData(writer io.Writer, data *Tabdata) { func printYamlData(writer io.Writer, data *Tabdata) {
type Data struct { type Data struct {
Entries []map[string]interface{} `yaml:"entries"` Entries []map[string]interface{} `yaml:"entries"`

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 {
@@ -125,6 +125,31 @@ ceta,33d12h,9,06/Jan/2008 15:04:05 -0700`,
NAME="beta" DURATION="1d10h5m1s" COUNT="33" WHEN="3/1/2014" NAME="beta" DURATION="1d10h5m1s" COUNT="33" WHEN="3/1/2014"
NAME="alpha" DURATION="4h35m" COUNT="170" WHEN="2013-Feb-03" NAME="alpha" DURATION="4h35m" COUNT="170" WHEN="2013-Feb-03"
NAME="ceta" DURATION="33d12h" COUNT="9" WHEN="06/Jan/2008 15:04:05 -0700"`, NAME="ceta" DURATION="33d12h" COUNT="9" WHEN="06/Jan/2008 15:04:05 -0700"`,
},
{
name: "json",
mode: cfg.Json,
numberize: false,
expect: `[
{
"COUNT": 33,
"DURATION": "1d10h5m1s",
"NAME": "beta",
"WHEN": "3/1/2014"
},
{
"COUNT": 170,
"DURATION": "4h35m",
"NAME": "alpha",
"WHEN": "2013-Feb-03"
},
{
"COUNT": 9,
"DURATION": "33d12h",
"NAME": "ceta",
"WHEN": "06/Jan/2008 15:04:05 -0700"
}
]`,
}, },
{ {
name: "yaml", name: "yaml",

View File

@@ -24,7 +24,7 @@ import (
"strconv" "strconv"
"github.com/araddon/dateparse" "github.com/araddon/dateparse"
"github.com/tlinden/tablizer/cfg" "codeberg.org/scip/tablizer/cfg"
) )
func sortTable(conf cfg.Config, data *Tabdata) { func sortTable(conf cfg.Config, data *Tabdata) {

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

@@ -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}/

View File

@@ -133,7 +133,7 @@
.\" ======================================================================== .\" ========================================================================
.\" .\"
.IX Title "TABLIZER 1" .IX Title "TABLIZER 1"
.TH TABLIZER 1 "2025-10-09" "1" "User Commands" .TH TABLIZER 1 "2025-10-13" "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
@@ -160,6 +160,8 @@ tablizer \- Manipulate tabular output of other programs
\& \-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
\& \-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
\& \-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
@@ -167,12 +169,13 @@ tablizer \- Manipulate tabular output of other programs
\& \-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
\& \-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
@@ -674,7 +677,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

@@ -21,6 +21,8 @@ tablizer - Manipulate tabular output of other programs
-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
-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
-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
@@ -28,12 +30,13 @@ tablizer - Manipulate tabular output of other programs
-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
-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
@@ -510,7 +513,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