diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0e8469e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +format diff --git a/main.go b/main.go new file mode 100644 index 0000000..3c429cb --- /dev/null +++ b/main.go @@ -0,0 +1,83 @@ +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 optionally 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 +}