replace matches in input if input pattern does not match a whole line (grep functionality)
This commit is contained in:
		
							
								
								
									
										52
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								main.go
									
									
									
									
									
								
							@ -10,6 +10,8 @@ import (
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"unicode/utf8"
 | 
			
		||||
 | 
			
		||||
	"github.com/fatih/color"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
@ -58,10 +60,37 @@ func main() {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	escapedOutput := EscSeqReplacer.Replace(*output)
 | 
			
		||||
	matchesWholeLine := strings.HasPrefix(*input, "^") && strings.HasSuffix(*input, "$")
 | 
			
		||||
 | 
			
		||||
	if matchesWholeLine {
 | 
			
		||||
		escapedOutput := EscSeqReplacer.Replace(*output)
 | 
			
		||||
		handleWholeLineRegex(pattern, escapedOutput)
 | 
			
		||||
	} else {
 | 
			
		||||
		handleInlineRegex(pattern)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// handleWholeLineRegex is using input pattern ot replace
 | 
			
		||||
// placeholders in output pattern with the given subgroups
 | 
			
		||||
func handleWholeLineRegex(pattern *regexp.Regexp, output string) {
 | 
			
		||||
	for line := range readLines(os.Stdin) {
 | 
			
		||||
		matches := pattern.FindStringSubmatch(line)
 | 
			
		||||
		if len(matches) == 0 {
 | 
			
		||||
			if *keepUnmatched {
 | 
			
		||||
				fmt.Println(line)
 | 
			
		||||
			}
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		fmt.Println(replaceVars(output, matches...))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// handleInlineRegex is using input pattern
 | 
			
		||||
// and color-codes all matches within input
 | 
			
		||||
func handleInlineRegex(pattern *regexp.Regexp) {
 | 
			
		||||
	c := color.New(color.FgRed, color.Bold)
 | 
			
		||||
	for line := range readLines(os.Stdin) {
 | 
			
		||||
		matches := pattern.FindAllStringIndex(line, -1)
 | 
			
		||||
 | 
			
		||||
		if len(matches) == 0 {
 | 
			
		||||
			if *keepUnmatched {
 | 
			
		||||
@ -70,7 +99,26 @@ func main() {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		fmt.Println(replaceVars(escapedOutput, matches...))
 | 
			
		||||
		runes := []rune(line)
 | 
			
		||||
		b := new(strings.Builder)
 | 
			
		||||
		nextMatch := 0
 | 
			
		||||
		currentIndex := 0
 | 
			
		||||
		for currentRune := 0; currentRune < len(runes); currentRune++ {
 | 
			
		||||
			if nextMatch >= len(matches) || currentIndex < matches[nextMatch][0] {
 | 
			
		||||
				// handle next rune
 | 
			
		||||
				b.WriteRune(runes[currentRune])
 | 
			
		||||
				currentIndex += utf8.RuneLen(runes[currentRune])
 | 
			
		||||
			} else {
 | 
			
		||||
				// handle next match
 | 
			
		||||
				match := line[matches[nextMatch][0]:matches[nextMatch][1]]
 | 
			
		||||
				b.WriteString(c.Sprint(match))
 | 
			
		||||
				currentIndex += len(match)
 | 
			
		||||
				currentRune += utf8.RuneCountInString(match) - 1
 | 
			
		||||
				nextMatch++
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		fmt.Println(b.String())
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user