September 10th 2015

Joining strings in POSIX shell

A common programming task is to glue (or "join") items together to create a single string. For example:

>>> ', '.join(['foo', 'bar', 'baz'])
"foo, bar, baz"

Notice that we have three items but only two commas — this can be important if the tool we passing doesn't support trailing delimiters or we simply want the result to be human-readable.

Unfortunately, this can be inconvenient in POSIX shell where we construct strings via explicit concatenation. A naïve solution of:

RESULT=""
for X in foo bar baz
do
    RESULT="${RESULT}, ${X}"
done

... incorrectly returns ", foo, bar, baz". We can solve this with a (cumbersome) counter or flag to only attach the delimiter when we need it:

COUNT=0
RESULT=""
for X in foo bar baz
do
    if [ "${COUNT}" = 0 ]
    then
        RESULT="${X}"
    else
        RESULT="${RESULT}, ${X}"
    fi
    COUNT=$((COUNT + 1))
done

One alternative is to use the little-known ":+" expansion modifier. Many people are familiar with ":-" for returning default values:

$ echo ${VAR:-fallback}

By contrast, the ":+" modifier inverts this logic, returning the fallback if the specified variable is actually set. This results in the elegant:

RESULT=""
for X in foo bar baz
do
    RESULT="${RESULT:+${RESULT}, }${X}"
done



You can subscribe to new posts via email or RSS.