treat data until EOF as new line and parse escape sequences

This commit is contained in:
Timon Ringwald 2022-05-06 10:51:52 +02:00
parent 9cb57b5aa0
commit 06648c9177
2 changed files with 36 additions and 6 deletions

14
esc_seq.go Normal file
View File

@ -0,0 +1,14 @@
package main
import "strings"
var EscSeqReplacer = strings.NewReplacer(
`\\`, `\`,
`\n`, "\n",
`\t`, "\t",
`\f`, "\f",
`\r`, "\r",
`\v`, "\v",
`\b`, "\b",
`\a`, "\a",
)

28
main.go
View File

@ -10,11 +10,12 @@ import (
"regexp"
"strconv"
"strings"
"unicode/utf8"
)
var (
// regex with sub groups
input = flag.String("i", "^.*?$", "input pattern")
input = flag.String("i", `^(.|\n)*?$`, "input pattern")
// format string with {0} as placeholders
// {0} always matches the whole line
@ -58,8 +59,9 @@ func main() {
panic(err)
}
escapedOutput := EscSeqReplacer.Replace(*output)
for line := range readLines(os.Stdin) {
line = line[:len(line)-1]
matches := pattern.FindStringSubmatch(line)
if len(matches) == 0 {
@ -69,7 +71,7 @@ func main() {
continue
}
fmt.Println(replaceVars(*output, matches...))
fmt.Println(replaceVars(escapedOutput, matches...))
}
}
@ -85,16 +87,30 @@ func readLines(r io.Reader) <-chan string {
var line string
var err error
lines := make([]string, 0, *lineParseAmount)
for line, err = r.ReadString('\n'); err == nil; line, err = r.ReadString('\n') {
for line, err = r.ReadString('\n'); ; line, err = r.ReadString('\n') {
if rn, size := utf8.DecodeLastRuneInString(line); rn == '\n' {
line = line[:len(line)-size]
}
lines = append(lines, line)
if len(lines) == cap(lines) {
// stop reading as soon as lineParseAmount is reached or an error occured (most likely EOF)
if len(lines) == cap(lines) || err != nil {
break
}
}
linesCombined := strings.Join(lines, "\n")
// use data as line if reading was successfull or EOF has been reached
// in the latter case: only use data if something could be read until EOF
if err == nil || err == io.EOF && linesCombined != "" {
out <- linesCombined
}
if err != nil {
return
}
out <- strings.Join(lines, "")
}
}(ch, r)