// // section-parse.go: scan standard input and do the following: // // 1. look for a section that begins with "test-text "STUFF/foo" and ends // with a blank line. // 2. print the "bar.DIGITS" suffix for each line in the section // // Build: // // go build section-parse.go // // Alternatively, you can run this script directly like this: // // go run ./section-parse.go < input.txt // // Example: // // > go run ./section-parse.go < input.txt // bar.1 // bar.2 // bar.3 // bar.4 // package main import ( "fmt" "io" "log" "os" "regexp" "strings" ) // section header regex var headerRe = regexp.MustCompile(`^test-text ".*/foo"$`) // section footer regex var footerRe = regexp.MustCompile(`^\s*$`) // body line regex var bodyRe = regexp.MustCompile(`^.*(bar\.\d+)$`) // Is the given line a section header? func isHeader(s string) bool { return headerRe.MatchString(s) } // Is the given line a section footer? func isFooter(s string) bool { return footerRe.MatchString(s) } // Read slice of lines from standard input. func getLines() []string { // read from standard input buf, err := io.ReadAll(os.Stdin) if err != nil { log.Fatal(err) } // split into lines, return result return strings.Split(string(buf), "\n") } func main() { inBody := false // walk lines for _, line := range(getLines()) { if (!inBody && isHeader(line)) || (inBody && isFooter(line)) { // toggle state inBody = !inBody } else if inBody { // match digits, check for error md := bodyRe.FindStringSubmatch(line) if len(md) < 2 { log.Fatalf("invalid body line: %s", line) } // print match to standard output fmt.Println(md[1]) } } }