Is it possible to do a double substitution with a shell string?

Solution 1:

As far as I know, the only way to do it in current versions of bash is in two steps e.g.

$ string="Mark Shuttleworth"
$ string="${string//a/o}"; echo "${string//t/g}"
Mork Shuggleworgh

Attempts to nest substitutions result in an error:

$ echo "${${string//a/o}//t/g}"
bash: ${${string//a/o}//t/g}: bad substitution

Note that other shells may support such nested substitutions e.g. in zsh 5.2:

~ % string="Mark Shuttleworth"
~ % echo "${${string//a/o}//t/g}"
Mork Shuggleworgh

Of course, external tools such as tr, sed, perl can do it easily

$ sed 'y/at/og/' <<< "$string"
Mork Shuggleworgh

$ perl -pe 'tr /at/og/' <<< "$string"
Mork Shuggleworgh

$ tr at og <<< "$string"
Mork Shuggleworgh

Solution 2:

You're substituting single letters, so just use tr:

tr at og

This causes each a to be replaced by o and each t to be replaced by g. With your example:

ek@Io:~$ tr at og <<<'Mark Shuttleworth'
Mork Shuggleworgh