Skip to content

Commit 46c9740

Browse files
committed
Improve replace mechanism
- Replace --whole-line with --replace-line - Fixed some bugs and issues - Add --regex-backrefs
1 parent 9948814 commit 46c9740

File tree

2 files changed

+34
-52
lines changed

2 files changed

+34
-52
lines changed

README.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,16 @@ Usage:
99
goreplace
1010
1111
Application Options:
12-
-s, --search= search term
13-
-r, --replace= replacement term
14-
-i, --ignore-case ignore pattern case
15-
--whole-line replace whole line
16-
--regex treat pattern as regex
17-
-v, --verbose verbose mode
18-
--dry-run dry run mode
19-
-V, --version show version and exit
20-
-h, --help show this help message
12+
-s, --search= search term
13+
-r, --replace= replacement term
14+
-i, --ignore-case ignore pattern case
15+
--replace-line replace whole line instead of only match
16+
--regex treat pattern as regex
17+
--regex-backrefs enable backreferences in replace term
18+
-v, --verbose verbose mode
19+
--dry-run dry run mode
20+
-V, --version show version and exit
21+
-h, --help show this help message
2122
```
2223

2324
### Examples
@@ -27,4 +28,4 @@ Application Options:
2728
| `goreplace -s foobar -r barfoo file1 file2` | Replaces `foobar` to `barfoo` in file1 and file2 |
2829
| `goreplace --regex -s 'foo.*' -r barfoo file1 file2` | Replaces the regex `foo.*` to `barfoo` in file1 and file2 |
2930
| `goreplace --regex --ignore-case -s 'foo.*' -r barfoo file1 file2` | Replaces the regex `foo.*` (and ignore case) to `barfoo` in file1 and file2 |
30-
| `goreplace --whole-line -s 'foobar' -r barfoo file1 file2` | Replaces all lines with content `foobar` to `barfoo` (whole line) in file1 and file2 |
31+
| `goreplace --replace-line -s 'foobar' -r barfoo file1 file2` | Replaces all lines with content `foobar` to `barfoo` (whole line) in file1 and file2 |

goreplace.go

Lines changed: 23 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -22,35 +22,17 @@ var opts struct {
2222
SearchRegex *regexp.Regexp
2323
Replace string `short:"r" long:"replace" required:"true" description:"replacement term" `
2424
IgnoreCase bool `short:"i" long:"ignore-case" description:"ignore pattern case"`
25-
WholeLine bool ` long:"whole-line" description:"replace whole line"`
25+
ReplaceLine bool ` long:"replace-line" description:"replace whole line instead of only match"`
2626
Regex bool ` long:"regex" description:"treat pattern as regex"`
27+
RegexBackref bool ` long:"regex-backrefs" description:"enable backreferences in replace term"`
2728
Verbose bool `short:"v" long:"verbose" description:"verbose mode"`
2829
DryRun bool ` long:"dry-run" description:"dry run mode"`
2930
ShowVersion bool `short:"V" long:"version" description:"show version and exit"`
3031
ShowHelp bool `short:"h" long:"help" description:"show this help message"`
3132
}
3233

33-
// Replace content parts in file
34-
func replaceContentInFile(filepath string) {
35-
var err error
36-
37-
read, err := ioutil.ReadFile(filepath)
38-
if err != nil {
39-
panic(err)
40-
}
41-
42-
content, replaceStatus := replaceText(string(read))
43-
44-
if replaceStatus {
45-
writeContentToFile(filepath, content)
46-
} else {
47-
logMessage(fmt.Sprintf("%s no match", filepath))
48-
}
49-
50-
}
51-
5234
// Replace line (if match is found) in file
53-
func replaceLineInFile(filepath string) {
35+
func replaceInFile(filepath string) {
5436
file, err := os.Open(filepath)
5537
if err != nil {
5638
panic(err)
@@ -63,7 +45,13 @@ func replaceLineInFile(filepath string) {
6345
line, e := Readln(r)
6446
for e == nil {
6547
if searchMatch(line) {
66-
buffer.WriteString(opts.Replace + "\n")
48+
if opts.ReplaceLine {
49+
line = opts.Replace
50+
} else {
51+
line = replaceText(line)
52+
}
53+
54+
buffer.WriteString(line + "\n")
6755
replaceStatus = true
6856
} else {
6957
buffer.WriteString(line + "\n")
@@ -73,7 +61,7 @@ func replaceLineInFile(filepath string) {
7361
}
7462

7563
if replaceStatus {
76-
writeContentToFile(filepath, buffer.String())
64+
writeContentToFile(filepath, buffer)
7765
} else {
7866
logMessage(fmt.Sprintf("%s no match", filepath))
7967
}
@@ -106,30 +94,27 @@ func searchMatch(content string) (bool) {
10694
}
10795

10896
// Replace text in whole content based on search options
109-
func replaceText(content string) (string, bool) {
110-
status := false
111-
112-
if searchMatch(content) {
113-
status = true
114-
content = opts.SearchRegex.ReplaceAllString(content, opts.Replace)
97+
func replaceText(content string) (string) {
98+
if opts.RegexBackref {
99+
return opts.SearchRegex.ReplaceAllString(content, opts.Replace)
100+
} else {
101+
return opts.SearchRegex.ReplaceAllLiteralString(content, opts.Replace)
115102
}
116-
117-
return content, status
118103
}
119104

120105
// Write content to file
121-
func writeContentToFile(filepath string, content string) {
106+
func writeContentToFile(filepath string, content bytes.Buffer) {
122107
if opts.DryRun {
123108
title := fmt.Sprintf("%s:", filepath)
124109

125110
fmt.Println(title)
126111
fmt.Println(strings.Repeat("-", len(title)))
127-
fmt.Println(content)
112+
fmt.Println(content.String())
128113
fmt.Println()
129114
fmt.Println()
130115
} else {
131116
var err error
132-
err = ioutil.WriteFile(filepath, []byte(content), 0)
117+
err = ioutil.WriteFile(filepath, content.Bytes(), 0)
133118
if err != nil {
134119
panic(err)
135120
}
@@ -150,9 +135,9 @@ func logError(err error) {
150135
fmt.Printf("Error: %s\n", err)
151136
}
152137

153-
// Process search term
138+
// Build search term
154139
// Compiles regexp if regexp is used
155-
func processSearchTerm() {
140+
func buildSearchTerm() {
156141
var regex string
157142

158143
if opts.Regex {
@@ -208,17 +193,13 @@ func main() {
208193

209194
handleSpecialOptions(argparser, args)
210195

211-
processSearchTerm()
196+
buildSearchTerm()
212197

213198
for i := range args {
214199
var file string
215200
file = args[i]
216201

217-
if opts.WholeLine {
218-
replaceLineInFile(file)
219-
} else {
220-
replaceContentInFile(file)
221-
}
202+
replaceInFile(file)
222203
}
223204

224205
os.Exit(0)

0 commit comments

Comments
 (0)