replacestart

Unlike Bourne Again Shell (bash), POSIX shell does not have a native find/replace function for replacing a pattern at the start of 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     replacestart() # $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     replacestart() # $var_to_get $find $replace [$var_to_set]
10     {
11         eval local __string=\"\$$1\" || return
12         case "$__string" in $2*)
13             __string="$3${__string#$2}"
14         esac
15         eval ${4:-$1}=\"\$__string\"
16     }
17 fi
18 eval echo \"before=[\$$1]\"
19 replacestart "$@"
20 eval echo \" after=[\$${4:-$1}]\"

Last updated