Reputation: 3452
To replace substring in the bash string str
I use:
str=${str/$pattern/$new}
However, I'm presently writing a script which will be executed with ash
.
I have a string containing '/'
and I want to use the above syntax inorder to replace the '/'
in my string but it does not work.
I tried:
str=${str///a}
str=${str/\//a}
str=${str/'/'/a}
But they do not work
How I can fix that?
Upvotes: 16
Views: 7890
Reputation: 146
POSIX string substitutions can be used to create a 100% POSIX compatible function that does the replacement. For short strings, this is considerably faster than command substitution, especially under Cygwin, whose fork(2)
copies the parent process's address space on top of creating processes being generally slow in Windows.
replace_all() {
RIGHT=$1
R=
while [ -n "$RIGHT" ]; do
LEFT=${RIGHT%%$2*}
if [ "$LEFT" = "$RIGHT" ]; then
R=$R$RIGHT
return
fi
R=$R$LEFT$3
RIGHT=${RIGHT#*$2}
done
}
It works like this:
$ replace_all ' foo bar baz ' ' ' .
$ echo $R
.foo.bar.baz.
With regards to performance, replacing 25% of characters in a 512 byte string runs roughly 50 times faster with replace_all()
than command substitution under the Cygwin dash(1)
. However, the execution time evens out around 4 KiB.
Upvotes: 5
Reputation: 295687
This parameter expansion is a bash extension to POSIX sh. If you review the relevant section of IEEE standard 1003.1, you'll see that it isn't a required feature, so shells which promise only POSIX compliance, such as ash
, have no obligation to implement it, and no obligation for their implementations to hew to any particular standard of correctness should they do so anyhow..
If you want bash extensions, you need to use bash (or other ksh derivatives which are extended similarly).
In the interim, you can use other tools. For instance:
str=$(printf '%s' "$str" | tr '/' 'a')
or
str=$(printf '%s' "$str" | sed -e 's@/@a@g')
Upvotes: 20