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" "regexp"
"strconv" "strconv"
"strings" "strings"
"unicode/utf8"
) )
var ( var (
// regex with sub groups // regex with sub groups
input = flag.String("i", "^.*?$", "input pattern") input = flag.String("i", `^(.|\n)*?$`, "input pattern")
// format string with {0} as placeholders // format string with {0} as placeholders
// {0} always matches the whole line // {0} always matches the whole line
@ -58,8 +59,9 @@ func main() {
panic(err) panic(err)
} }
escapedOutput := EscSeqReplacer.Replace(*output)
for line := range readLines(os.Stdin) { for line := range readLines(os.Stdin) {
line = line[:len(line)-1]
matches := pattern.FindStringSubmatch(line) matches := pattern.FindStringSubmatch(line)
if len(matches) == 0 { if len(matches) == 0 {
@ -69,7 +71,7 @@ func main() {
continue 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 line string
var err error var err error
lines := make([]string, 0, *lineParseAmount) 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) 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 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 { if err != nil {
return return
} }
out <- strings.Join(lines, "")
} }
}(ch, r) }(ch, r)