# Kata Find and Replace ## Énoncé Programme qui trouve et remplace un mot par un autre dans un fichier. #### Exemple *Remplacer le mot **Go** par **Python***
Source: wikigo.txtRésultat
Go was conceived in 2007 to improve programming productivity at GooglePython was conceived in 2007 to improve programming productivity at Pythonogle
### Features - Affiche le résumé du traitement en console - Nombre d'occurrences du mot - Numéros de lignes modifiés - Écrire le texte modifié dans un nouveau fichier pour préserver l'original - Bonus : prendre aussi en compte que le mot peut avoir une majuscule (ou pas !) #### Exemple de résumé ```bash $ go run main.go == Summary == Number of occurrences of Go: 10 Number of lines: 7 Lines: [ 1 - 8 - 15 - 17 - 19 - 23 - 28 ] == End of Summary == ``` ### Prototypes ```go func ProcessLine(line, oldWord, newWord string) (found bool, result string, occurrences int) ``` - `line` : ligne à traiter - `oldWord` / `newWord` : ancien mot / nouveau mot - `found` : vrai si au moins une occurrence trouvée - `result` : résultat après traitement - `occurrences` : nombre d'occurrences de `oldWord` dans la ligne ```go func FindReplaceFile(src string, dst string, oldWord string, newWord string) (occurrences int, lines []int, err error) ``` - `src` : nom du fichier source - `oldWord` / `newWord` : ancien mot / nouveau mot - `occurrences` : nombre d'occurrences de `oldWord` - `lines` : tableau des numéros de lignes ou `oldWord` a été trouvé - `err` : erreur générée par la fonction

Astuce `FindReplaceFile` n'arrive pas à ouvrir le fichier, il faut renvoyer une erreur

## Outils ### Bufio ```go scanner := bufio.NewScanner(srcFile) for scanner.Scan() { t := scanner.Text() } ``` ```go writer := bufio.NewWriter(dstFile) defer writer.Flush() fmt.Fprintln(writer, "Texte d'une ligne") ``` ### Strings ```go c := strings.Contains("go ruby java", "go") // c == true cnt := strings.Count("go go go", "go") // cnt == 3 res := strings.Replace("old go", "go", "python", -1) // res == "old python" ``` ## Solution ```go package main import ( "bufio" "fmt" "os" "strings" ) func ProcessLine(line, oldWord, newWord string) (found bool, result string, occurrences int) { oldWordLower := strings.ToLower(oldWord) newWordLower := strings.ToLower(newWord) result = line if strings.Contains(line, oldWord) || strings.Contains(line, oldWordLower) { found = true occurrences += strings.Count(line, oldWord) occurrences += strings.Count(line, oldWordLower) result = strings.ReplaceAll(line, oldWord, newWord) result = strings.ReplaceAll(result, oldWordLower, newWordLower) } return found, result, occurrences } func FindReplaceFile(src string, dst string, oldWord string, newWord string) (occurrences int, lines []int, err error) { // open src file srcFile, errSrc := os.Open(src) if errSrc != nil { return 0, lines, errSrc } defer srcFile.Close() // open dst file dstFile, errDst := os.Create(dst) if errDst != nil { return 0, nil, errDst } defer dstFile.Close() oldWord = oldWord newWord = newWord lineIdx := 1 scanner := bufio.NewScanner(srcFile) writer := bufio.NewWriter(dstFile) defer writer.Flush() for scanner.Scan() { found, res, o := ProcessLine(scanner.Text(), oldWord, newWord) if found { occurrences += o lines = append(lines, lineIdx) } _, errWrt := fmt.Fprintln(writer, res) if errWrt != nil { return occurrences, lines, errWrt } lineIdx++ } return occurrences, lines, nil } func main() { oldWord := "Go" newWord := "Python" occurrences, lines, err := FindReplaceFile("wikigo.txt", "wikipython.txt", oldWord, newWord) if err != nil { fmt.Printf("Error while executing find replace: %v\n", err) return } fmt.Println("== Summary ==") defer fmt.Println("== End of Summary ==") fmt.Printf("Number of occurrences of %s: %d\n", oldWord, occurrences) fmt.Printf("Number of lines: %d\nLines: [ ", len(lines)) linesCount := len(lines) for i, l := range lines { fmt.Printf("%d", l) if i < linesCount-1 { fmt.Printf(" - ") } } fmt.Println(" ]") } ```