replace
Unlike Bourne Again Shell (bash), POSIX shell does not have a native find/replace function for replacing one occurrence of a pattern in a given string with another. Below is an implementation written in native POSIX shell that is:
  • Faster than piping to awk, sed, perl, python, ruby, or other langauge
  • Compatible with bash and all other POSIX-compliant shells
  • Optimized to use ${parameter/pattern[/string]} when bash is detected
1 #!/bin/sh
2 if [ "$BASH_VERSION" ]; then
3 replace() # $var_to_get $find $replace [$var_to_set]
4 {
5 eval ${4:-$1}=\"\${$1/\$2${3:+/\$3}}\"
6 }
7 else
8 # NB: On FreeBSD, sh(1) runs this faster than bash(1) runs the above
9 replace() # $var_to_get $find $replace [$var_to_set]
10 {
11 eval local __left= __right=\"\$1\" || return
12 case "$__right" in *$2*)
13 __left="${__right%%$2*}$3"
14 __right="${__right#*$2}"
15 esac
16 eval ${4:-$1}=\"\$__left\$__right\"
17 }
18 fi
19 eval echo \"before=[\$1]\"
20 replace "[email protected]"
21 eval echo \" after=[\${4:-$1}]\"
Copy link