diff --git a/cmd/root.go b/cmd/root.go
index ddd0d31..c8db5ec 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -18,33 +18,31 @@ package cmd
import (
"bytes"
- "github.com/tlinden/tablizer/lib"
"fmt"
"github.com/spf13/cobra"
+ "github.com/tlinden/tablizer/lib"
"log"
"os"
"os/exec"
)
-var helpCmd = &cobra.Command{
- Use: "help",
- Short: "Show documentation",
- Run: func(cmd *cobra.Command, args []string) {
- man := exec.Command("less", "-")
+var ShowManual = false
- var b bytes.Buffer
- b.Write([]byte(manpage))
+func man() {
+ man := exec.Command("less", "-")
- man.Stdout = os.Stdout
- man.Stdin = &b
- man.Stderr = os.Stderr
+ var b bytes.Buffer
+ b.Write([]byte(manpage))
- err := man.Run()
+ man.Stdout = os.Stdout
+ man.Stdin = &b
+ man.Stderr = os.Stderr
- if err != nil {
- log.Fatal(err)
- }
- },
+ err := man.Run()
+
+ if err != nil {
+ log.Fatal(err)
+ }
}
var rootCmd = &cobra.Command{
@@ -57,6 +55,11 @@ var rootCmd = &cobra.Command{
return nil
}
+ if ShowManual {
+ man()
+ return nil
+ }
+
err := lib.PrepareColumns()
if err != nil {
return err
@@ -81,7 +84,9 @@ func Execute() {
func init() {
rootCmd.PersistentFlags().BoolVarP(&lib.Debug, "debug", "d", false, "Enable debugging")
rootCmd.PersistentFlags().BoolVarP(&lib.NoNumbering, "no-numbering", "n", false, "Disable header numbering")
- rootCmd.PersistentFlags().BoolVarP(&lib.ShowVersion, "version", "v", false, "Print program version")
+ rootCmd.PersistentFlags().BoolVarP(&lib.ShowVersion, "version", "V", false, "Print program version")
+ rootCmd.PersistentFlags().BoolVarP(&lib.InvertMatch, "invert-match", "v", false, "select non-matching rows")
+ rootCmd.PersistentFlags().BoolVarP(&ShowManual, "man", "m", false, "Display manual page")
rootCmd.PersistentFlags().StringVarP(&lib.Separator, "separator", "s", "", "Custom field separator")
rootCmd.PersistentFlags().StringVarP(&lib.Columns, "columns", "c", "", "Only show the speficied columns (separated by ,)")
@@ -98,11 +103,4 @@ func init() {
// same thing but more common, takes precedence over above group
rootCmd.PersistentFlags().StringVarP(&lib.OutputMode, "output", "o", "", "Output mode - one of: orgtbl, markdown, extended, shell, ascii(default)")
-
- rootCmd.AddCommand(helpCmd)
-
- rootCmd.SetHelpCommand(&cobra.Command{
- Use: "no-help",
- Hidden: true,
- })
}
diff --git a/cmd/tablizer.go b/cmd/tablizer.go
index f7e26ad..b5d091e 100644
--- a/cmd/tablizer.go
+++ b/cmd/tablizer.go
@@ -11,6 +11,8 @@ SYNOPSIS
-c, --columns string Only show the speficied columns (separated by ,)
-d, --debug Enable debugging
-h, --help help for tablizer
+ -v, --invert-match select non-matching rows
+ -m, --man Display manual page
-n, --no-numbering Disable header numbering
-o, --output string Output mode - one of: orgtbl, markdown, extended, ascii(default)
-X, --extended Enable extended output
@@ -38,7 +40,8 @@ DESCRIPTION
Without any options it reads its input from "STDIN", but you can also
specify a file as a parameter. If you want to reduce the output by some
- regular expression, just specify it as its first parameters. Hence:
+ regular expression, just specify it as its first parameter. You may also
+ use the -v option to exclude all rows which match the pattern. Hence:
# read from STDIN
kubectl get pods | tablizer
diff --git a/lib/common.go b/lib/common.go
index dcda314..78b9c6c 100644
--- a/lib/common.go
+++ b/lib/common.go
@@ -31,12 +31,13 @@ var (
OutflagOrgtable bool
OutflagShell bool
OutputMode string
+ InvertMatch bool
// used for validation
validOutputmodes = "(orgtbl|markdown|extended|ascii)"
// main program version
- Version = "v1.0.4"
+ Version = "v1.0.5"
// generated version string, used by -v contains lib.Version on
// main branch, and lib.Version-$branch-$lastcommit-$date on
diff --git a/lib/parser.go b/lib/parser.go
index 53c0af6..ae7f50f 100644
--- a/lib/parser.go
+++ b/lib/parser.go
@@ -114,7 +114,11 @@ func parseFile(input io.Reader, pattern string) (Tabdata, error) {
} else {
// data processing
if len(pattern) > 0 {
- if !patternR.MatchString(line) {
+ if patternR.MatchString(line) == InvertMatch {
+ // by default -v is false, so if a line does NOT
+ // match the pattern, we will ignore it. However,
+ // if the user specified -v, the matching is inverted,
+ // so we ignore all lines, which DO match.
continue
}
}
@@ -151,7 +155,7 @@ func parseFile(input io.Reader, pattern string) (Tabdata, error) {
}
if scanner.Err() != nil {
- return data, errors.Unwrap(fmt.Errorf("Regexp pattern %s is invalid: %w", pattern, scanner.Err()))
+ return data, errors.Unwrap(fmt.Errorf("Failed to read from io.Reader: %w", scanner.Err()))
}
if Debug {
diff --git a/lib/parser_test.go b/lib/parser_test.go
index 24fca81..396f6a3 100644
--- a/lib/parser_test.go
+++ b/lib/parser_test.go
@@ -18,6 +18,7 @@ along with this program. If not, see .
package lib
import (
+ "fmt"
"reflect"
"strings"
"testing"
@@ -80,3 +81,57 @@ asd igig cxxxncnc
t.Errorf("Parser returned invalid data\nExp: %+v\nGot: %+v\n", data, gotdata)
}
}
+
+func TestParserPatternmatching(t *testing.T) {
+ var tests = []struct {
+ entries [][]string
+ pattern string
+ invert bool
+ }{
+ {
+ entries: [][]string{
+ []string{
+ "asd",
+ "igig",
+ "cxxxncnc",
+ },
+ },
+ pattern: "ig",
+ invert: false,
+ },
+ {
+ entries: [][]string{
+ []string{
+ "19191",
+ "EDD 1",
+ "X",
+ },
+ },
+ pattern: "ig",
+ invert: true,
+ },
+ }
+
+ table := `ONE TWO THREE
+asd igig cxxxncnc
+19191 EDD 1 X`
+
+ for _, tt := range tests {
+ testname := fmt.Sprintf("parse-with-inverted-pattern-%t", tt.invert)
+ t.Run(testname, func(t *testing.T) {
+ InvertMatch = tt.invert
+
+ readFd := strings.NewReader(table)
+ gotdata, err := parseFile(readFd, tt.pattern)
+
+ if err != nil {
+ t.Errorf("Parser returned error: %s\nData processed so far: %+v", err, gotdata)
+ }
+
+ if !reflect.DeepEqual(tt.entries, gotdata.entries) {
+ t.Errorf("Parser returned invalid data (pattern: %s, invert: %t)\nExp: %+v\nGot: %+v\n",
+ tt.pattern, tt.invert, tt.entries, gotdata.entries)
+ }
+ })
+ }
+}
diff --git a/tablizer.1 b/tablizer.1
index 92a1660..78fab95 100644
--- a/tablizer.1
+++ b/tablizer.1
@@ -133,7 +133,7 @@
.\" ========================================================================
.\"
.IX Title "TABLIZER 1"
-.TH TABLIZER 1 "2022-10-04" "1" "User Commands"
+.TH TABLIZER 1 "2022-10-05" "1" "User Commands"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
@@ -150,6 +150,8 @@ tablizer \- Manipulate tabular output of other programs
\& \-c, \-\-columns string Only show the speficied columns (separated by ,)
\& \-d, \-\-debug Enable debugging
\& \-h, \-\-help help for tablizer
+\& \-v, \-\-invert\-match select non\-matching rows
+\& \-m, \-\-man Display manual page
\& \-n, \-\-no\-numbering Disable header numbering
\& \-o, \-\-output string Output mode \- one of: orgtbl, markdown, extended, ascii(default)
\& \-X, \-\-extended Enable extended output
@@ -179,8 +181,9 @@ positions.
.PP
Without any options it reads its input from \f(CW\*(C`STDIN\*(C'\fR, but you can also
specify a file as a parameter. If you want to reduce the output by
-some regular expression, just specify it as its first
-parameters. Hence:
+some regular expression, just specify it as its first parameter. You
+may also use the \fB\-v\fR option to exclude all rows which match the
+pattern. Hence:
.PP
.Vb 2
\& # read from STDIN
diff --git a/tablizer.pod b/tablizer.pod
index 0451bbc..f3137e4 100644
--- a/tablizer.pod
+++ b/tablizer.pod
@@ -11,6 +11,8 @@ tablizer - Manipulate tabular output of other programs
-c, --columns string Only show the speficied columns (separated by ,)
-d, --debug Enable debugging
-h, --help help for tablizer
+ -v, --invert-match select non-matching rows
+ -m, --man Display manual page
-n, --no-numbering Disable header numbering
-o, --output string Output mode - one of: orgtbl, markdown, extended, ascii(default)
-X, --extended Enable extended output
@@ -41,8 +43,9 @@ positions.
Without any options it reads its input from C, but you can also
specify a file as a parameter. If you want to reduce the output by
-some regular expression, just specify it as its first
-parameters. Hence:
+some regular expression, just specify it as its first parameter. You
+may also use the B<-v> option to exclude all rows which match the
+pattern. Hence:
# read from STDIN
kubectl get pods | tablizer