Advanced parameter substitution with bash

I’m tired of looking up information on how to use those special fancy features to do parameter substitution in bash scripts, so I’ve decided to blog about it (at least some of the more useful ones). It’ll be quicker to find it this way than to Google it again.

First off, let me demonstrate with a sample:


The :- says that if KDEDOCS is unset (or is set to a null value), then to use default as the result. The original variable is left unchanged.

There are other useful ones, which I’ll summarize here. For more definitive information, consult the Advanced Bash Scripting Parameter Substitution page, which is where I found the explanations. Also, as you may guess from the page title, some of these substitutions are specific to the bash shell. The example I gave seems to work on plain sh compatible shells though, but I can’t check.

Substitution Syntax Action
${VAR<b>-</b>default} If VAR is set (to any value, even null) then return $VAR, otherwise return the default provided. VAR is unchanged. If you use :- instead of -, then the default is also used when VAR is set to null.
${VAR<b>=</b>default} This is exactly like doing ${VAR-default}, except that VAR is set to the result as well. You may also use := instead of =, which has exactly the same difference.
${#VAR} This returns the number of characters in VAR. Note: I am not clear how this works with Unicode. I would assume that by characters they mean actual characters and not bytes, but I don't know.
${VAR<b>#</b>pattern} This returns VAR with the shortest instance of pattern removed from the front. pattern itself is a shell-style glob, not a regular expression. If you use ## instead of #, then the longest matching pattern is removed instead of the shortest.
${VAR<b>%</b>pattern> Exactly the same as above, except that it applies to the back of VAR, not the front.

Apparently the following options were taken from ksh. So, you can assume that they’re not plain sh compatible:

Substitution Syntax Action
${VAR:pos} Returns $VAR, expanding from pos instead of the beginning.
${VAR:pos:len} Same as above, except that no more than len characters are expanded.
${VAR/pat/replacement} Returns VAR with the first instance of the shell-glob-style pat replaced with replacement. If you use //pat instead of /pat then all instances are replaced, not just the first.

So, intrepid bash hackers, put these tips to good use!