Bash – pure shell complex substitution in variable

bashkshshellvariable substitution

Is there any way to substitute text in variables on several patterns at time or even using back reference?

For example, I have FILE=filename.ext and I want to change it to filename_sometext.ext. But I don't know that file extension is .ext. All I know about it is that extension is after last dot.
So I can do it in two steps:

EXT=${FILE##*.}
FILE=${FILE%.*}_sometext.$EXT

Can I do it on one step (something like ${FILE/.\(*\)/_sometext.\1} [that doesn't work])?

By the way I need to do it in pure shell without sed/awk/etc. My shell is ksh, but if there is way to do it with bashisms I'd like to know it too.

Best Answer

Bash Parameter Expansion says that the variable (FILE in your example) must be a parameter name. So they don't nest. And the last part of ${param/pattern/replacement} must be a string. So back references aren't supported.

My only advice is to use

${EXT:+.$EXT}

to avoid adding a trailing dot if the file has no extension.


UPDATE

Apparently back references are supported in ksh93.

So you could use something like

FILE="${FILE/@(.*)/_something\1}"
Related Question