diff --git a/src/app.go b/src/app.go index 901188a..bbd81f0 100644 --- a/src/app.go +++ b/src/app.go @@ -85,7 +85,7 @@ func GetApp() *cli.App { }, Usage: "F2 is a command-line tool for batch renaming multiple files and directories quickly and safely", UsageText: "FLAGS [OPTIONS] [PATHS...]", - Version: "v1.5.3", + Version: "v1.5.6", EnableBashCompletion: true, Flags: []cli.Flag{ &cli.StringFlag{ @@ -98,7 +98,7 @@ func GetApp() *cli.App { Aliases: []string{"r"}, Usage: "Replacement ``. If omitted, defaults to an empty string. Supports built-in and regex capture variables", }, - &cli.UintFlag{ + &cli.IntFlag{ Name: "replace-limit", Aliases: []string{"l"}, Usage: "Limit the number of replacements to be made (replaces all matches if set to 0)", diff --git a/src/operation.go b/src/operation.go index c35f55b..5db8f9d 100644 --- a/src/operation.go +++ b/src/operation.go @@ -556,7 +556,7 @@ func setOptions(op *Operation, c *cli.Context) error { op.maxDepth = int(c.Uint("max-depth")) op.quiet = c.Bool("quiet") op.revert = c.Bool("undo") - op.replaceLimit = int(c.Uint("replace-limit")) + op.replaceLimit = c.Int("replace-limit") // Sorting if c.String("sort") != "" { diff --git a/src/replace.go b/src/replace.go index c75bfad..650ee0e 100644 --- a/src/replace.go +++ b/src/replace.go @@ -389,7 +389,9 @@ func (op *Operation) regexReplace( fileName, replacement string, ) string { var output string - if op.replaceLimit > 0 { + + switch limit := op.replaceLimit; { + case limit > 0: counter := 0 output = r.ReplaceAllStringFunc( fileName, @@ -402,7 +404,23 @@ func (op *Operation) regexReplace( return r.ReplaceAllString(val, replacement) }, ) - } else { + case limit < 0: + matches := r.FindAllString(fileName, -1) + + l := len(matches) + limit + counter := 0 + output = r.ReplaceAllStringFunc( + fileName, + func(val string) string { + if counter >= l { + return r.ReplaceAllString(val, replacement) + } + + counter++ + return val + }, + ) + default: output = r.ReplaceAllString(fileName, replacement) } diff --git a/src/replace_test.go b/src/replace_test.go index ea1513b..7ce8823 100644 --- a/src/replace_test.go +++ b/src/replace_test.go @@ -10,6 +10,93 @@ func TestFindReplace(t *testing.T) { testDir := setupFileSystem(t) cases := []testCase{ + { + name: "Replace the last 2 matches", + want: []Change{ + { + Source: "No Pressure (2021) S1.E1.1080p.mkv", + BaseDir: testDir, + Target: "No Pressure (2021) S1.E5.5080p.mkv", + }, + { + Source: "No Pressure (2021) S1.E2.1080p.mkv", + BaseDir: testDir, + Target: "No Pressure (2021) S5.E2.5080p.mkv", + }, + { + Source: "No Pressure (2021) S1.E3.1080p.mkv", + BaseDir: testDir, + Target: "No Pressure (2021) S5.E3.5080p.mkv", + }, + }, + args: []string{ + "-f", + "1", + "-r", + "5", + "-l", + "-2", + testDir, + }, + }, + { + name: "Replace the last match", + want: []Change{ + { + Source: "No Pressure (2021) S1.E1.1080p.mkv", + BaseDir: testDir, + Target: "No Pressure (2021) S1.E1.5080p.mkv", + }, + { + Source: "No Pressure (2021) S1.E2.1080p.mkv", + BaseDir: testDir, + Target: "No Pressure (2021) S1.E2.5080p.mkv", + }, + { + Source: "No Pressure (2021) S1.E3.1080p.mkv", + BaseDir: testDir, + Target: "No Pressure (2021) S1.E3.5080p.mkv", + }, + }, + args: []string{ + "-f", + "1", + "-r", + "5", + "-l", + "-1", + testDir, + }, + }, + { + name: "Replace the first 10 matches", + want: []Change{ + { + Source: "No Pressure (2021) S1.E1.1080p.mkv", + BaseDir: testDir, + Target: "No Pressure (2025) S5.E5.5080p.mkv", + }, + { + Source: "No Pressure (2021) S1.E2.1080p.mkv", + BaseDir: testDir, + Target: "No Pressure (2025) S5.E2.5080p.mkv", + }, + { + Source: "No Pressure (2021) S1.E3.1080p.mkv", + BaseDir: testDir, + Target: "No Pressure (2025) S5.E3.5080p.mkv", + }, + }, + args: []string{ + "-f", + "1", + "-r", + "5", + "-l", + "10", + testDir, + }, + }, { want: []Change{ {