Jordan Mackie
Jordan Mackie

Reputation: 2406

Replace Last Occurrence of Substring in String (bash)

From the bash software manual:

${parameter/pattern/string}

The pattern is expanded to produce a pattern just as in filename expansion. Parameter is expanded and the longest match of pattern against its value is replaced with string.
... If pattern begins with ‘%’, it must match at the end of the expanded value of parameter.

And so I've tried:

local new_name=${file/%old/new}

Where string is an absolute file path (/abc/defg/hij and old and new are variable strings.

However this seems to be trying to match the literal %sb1.

What is the syntax for this?

Expected Output:

Given

old=sb1
new=sb2

Then

/foo/sb1/foo/bar/sb1 should become /foo/sb1/foo/bar/sb2

/foo/foosb1other/foo/bar/foosb1bar should become /foo/foosb1other/foo/bar/foosb2bar

Upvotes: 4

Views: 4794

Answers (1)

Charles Duffy
Charles Duffy

Reputation: 295373

Using only shell-builtin parameter expansion:

src=sb1; dest=sb2
old=/foo/foosb1other/foo/bar/foosb1bar

if [[ $old = *"$src"* ]]; then
  prefix=${old%"$src"*}                  # Extract content before the last instance
  suffix=${old#"$prefix"}                # Extract content *after* our prefix
  new=${prefix}${suffix/"$src"/"$dest"}  # Append unmodified prefix w/ suffix w/ replacement
else
  new=$old
fi

declare -p new >&2

...properly emits:

declare -- new="/foo/foosb1other/foo/bar/foosb2bar"

Upvotes: 4

Related Questions