format/main.go
2021-08-20 23:47:41 +02:00

84 lines
2.0 KiB
Go

package main
import (
"bufio"
"flag"
"fmt"
"os"
"regexp"
"strconv"
"strings"
)
var (
// regex with sub groups
input = flag.String("i", "^.*?$", "input pattern")
// format string with {0} as placeholders
// {0} always matches the whole line
// {1} and onwards match their respective sub groups
// You can optionall specify a printf-syntax for formatting like this: {1:%s} or {1:%02d}
// printf-syntax is currently supported for: strings, floats, integers
output = flag.String("o", "{0}", "output pattern")
// don't ignore lines which do not match against input.
// they will be copied without any changes
keepUnmatched = flag.Bool("k", false, "keep unmatched lines")
replacePattern = regexp.MustCompile(`\{(\d+)(?::(.*?))?\}`)
)
func main() {
flag.Parse()
pattern, err := regexp.Compile(*input)
if err != nil {
panic(err)
}
r := bufio.NewReader(os.Stdin)
for line, err := r.ReadString('\n'); err == nil; line, err = r.ReadString('\n') {
line = line[:len(line)-1]
matches := pattern.FindStringSubmatch(line)
fmt.Println(matches)
if len(matches) == 0 {
if *keepUnmatched {
fmt.Println(line)
}
continue
}
fmt.Println(replaceVars(*output, matches...))
}
}
func replaceVars(format string, vars ...string) string {
replacements := replacePattern.FindAllStringSubmatch(format, -1)
for _, replacement := range replacements {
rplStr := replacement[0]
varIndex, _ := strconv.Atoi(replacement[1])
rplFmt := replacement[2]
// default format if not specified by user
if rplFmt == "" {
rplFmt = "%s"
}
if strings.HasSuffix(rplFmt, "d") { // replace integers
value, _ := strconv.ParseInt(vars[varIndex], 10, 64)
format = strings.Replace(format, rplStr, fmt.Sprintf(rplFmt, value), 1)
} else if strings.HasSuffix(rplFmt, "f") { // replace floats
value, _ := strconv.ParseFloat(vars[varIndex], 64)
format = strings.Replace(format, rplStr, fmt.Sprintf(rplFmt, value), 1)
} else { // replace strings
format = strings.Replace(format, rplStr, fmt.Sprintf(rplFmt, vars[varIndex]), 1)
}
}
return format
}