What does the curly-brace syntax ${var%.*} mean?

I was reviewing some of my old code and came across this syntax:

extractDir="${downloadFileName%.*}-tmp"

The only information I found searching refers to a list of commands, but this is just one variable. What does this curly-brace syntax mean in bash?


In this context, it is a parameter substitution.

The ${variable%.*} notation means take the value of $variable, strip off the pattern .* from the tail of the value — mnemonic: percenT has a 't' at the Tail — and give the result. (By contrast, ${variable#xyz} means remove xyz from the head of the variable's value — mnemonic: a Hash has an 'h' at the Head.)

Given:

downloadFileName=abc.tar.gz

evaluating extractDir="${downloadFileName%.*}-tmp" yields the equivalent of:

extractDir="abc.tar-tmp"

The alternative notation with the double %:

extractDir="${downloadFileName%%.*}-tmp"

would yield the equivalent of:

extractDir="abc-tmp"

The %% means remove the longest possible tail; correspondingly, ## means remove the longest matching head.


It indicates that parameter expansion will occur.