package main import ( "bufio" "flag" "fmt" "os" "regexp" "strconv" "strings" ) var ( input = flag.String("i", "^.*?$", "input pattern") output = flag.String("o", "{0}", "output pattern") 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 }