Skip to content

Commit

Permalink
Add columns filter
Browse files Browse the repository at this point in the history
Add columns(delimiter string, columns string) filter that writes the
selected 'columns' in the order provided where 'columns' is a 1-indexed
comma separated list of column positions. Columns are defined by
splitting with the 'delimiter'.
  • Loading branch information
dyson committed Oct 28, 2022
1 parent 894d50c commit 37a5de6
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 9 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ first line of the input and return all other lines.

| Filter | |
| ------ | ------- |
| Columns() | TODO |
| Columns(delimiter *string*, columns *string*) | Returns the selected `columns` in order where `columns` is a 1-indexed comma separated list of column positions. Columns are defined by splitting with the 'delimiter'. |
| CountLines() | Returns the line count. Lines are delimited by `\r?\n`. |
| CountRunes() | Returns the rune (Unicode code points) count. Erroneous and short encodings are treated as single runes of width 1 byte. |
| CountWords() | Returns the word count. Words are delimited by<br />`\t\|\n\|\v\|\f\|\r\| \|0x85\|0xA0`. |
Expand Down
45 changes: 37 additions & 8 deletions pkg/pipeline/filters.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (

var (
Filters = map[string]reflect.Value{
// "columns": reflect.ValueOf(Columns),
"columns": reflect.ValueOf(Columns),
"countlines": reflect.ValueOf(CountLines),
"countrunes": reflect.ValueOf(CountRunes),
"countwords": reflect.ValueOf(CountWords),
Expand All @@ -34,11 +34,39 @@ var (
}
)

// TODO
func Columns(delimiter int, columns string) func(io.Reader, io.Writer) error {
// Columns returns a filter that writes the selected 'columns' in the order
// provided where 'columns' is a 1-indexed comma separated list of column positions.
// Columns are defined by splitting with the 'delimiter'.
func Columns(delimiter string, columns string) func(io.Reader, io.Writer) error {
return func(r io.Reader, w io.Writer) error {
return nil
order := []int{}
for _, column := range strings.Split(columns, ",") {
index, err := strconv.Atoi(strings.TrimSpace(column))
if err != nil {
return fmt.Errorf("list of columns must be comma serarated list of ints, got: %v", columns)
}

order = append(order, index)
}

scanner := bufio.NewScanner(r)

for scanner.Scan() {
lineColumns := strings.Split(scanner.Text(), delimiter)

output := []string{}
for _, v := range order {
if v-1 < len(lineColumns) {
output = append(output, lineColumns[v-1])
}
}

fmt.Fprintln(w, strings.Join(output, delimiter))
}

return scanner.Err()
}

}

// CountLines returns a filter that writes the number of lines read.
Expand Down Expand Up @@ -134,7 +162,8 @@ func NotFirst(n int) func(io.Reader, io.Writer) error {
}
}

// Join returns a filter that writes all lines as a single string separated by 'delimiter'.
// Join returns a filter that writes all lines as a single string separated by
// 'delimiter'.
func Join(delimiter string) func(io.Reader, io.Writer) error {
return func(r io.Reader, w io.Writer) error {
scanner := bufio.NewScanner(r)
Expand Down Expand Up @@ -338,9 +367,9 @@ func ReplaceRegex(regex *regexp.Regexp, replace string) func(io.Reader, io.Write

// MIT License

// Frequency returns a filter that writes unique lines from the input, prefixed with a frequency
// count, in descending numerical order (most frequent lines first). Lines with
// equal frequency will be sorted alphabetically.
// Frequency returns a filter that writes unique lines from the input, prefixed
// with a frequency count, in descending numerical order (most frequent lines
// first). Lines with equal frequency will be sorted alphabetically.
//
// This is a common pattern in shell scripts to find the most
// frequently-occurring lines in a file:
Expand Down
3 changes: 3 additions & 0 deletions pkg/pipeline/filters_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ func TestFilters(t *testing.T) {
input string
want string
}{
{Columns(",", "3,2,1"), "one\t\tthree\n", "one\t\tthree\n"},
{Columns("\t", "9"), "one\t\tthree\n", "\n"},
{Columns("\t", "3,2,1"), "one\t\tthree\n", "three\t\tone\n"},
{CountLines(), "", "0\n"},
{CountLines(), input, "3\n"},
{CountRunes(), "", "0\n"},
Expand Down

0 comments on commit 37a5de6

Please sign in to comment.