Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm trying to use the bash substring built-in to replace the output of a subshell or another bash function.

The following commands works quite well in zsh; but results in a bad substitution error in bash:



${$(basename $PWD)//trunk/latest}

the output should be the last folder of the $PWD, replaced by latest when my current directory is trunk

so /home/user/trunk should become latest

Is there a bash equivalent allowing to chain strings editions without relying on variables or pipes ? Or do bash built-ins only allows the input to be a string or a plain variable ?

share|improve this question
up vote 8 down vote accepted

No, that nesting of substitution operators is unique to zsh.

Note that with zsh like with (t)csh, you can also do ${PWD:t:s/trunk/latest/}.

Though bash also supports those csh history modifiers for history expansion, it doesn't support them for its parameter expansions.

Here with bash, use a temporary variable:

var=${PWD##*/} var=${var//trunk/latest}
share|improve this answer

Try this with bash:

[[ $PWD =~ .*/(.*) ]] && echo "${BASH_REMATCH[1]//trunk/latest}"

or with one command:

[[ $PWD =~ .*/(.*) && ${BASH_REMATCH[1]//trunk/latest} =~ (.*) ]]

The result is in ${BASH_REMATCH[1]}

share|improve this answer

do you want...?


I don't see a method to your request. If you want to replace all of $PWD w/ latest - though the best way to do that is to cd to latest.

[ /home/user/trunk = "$PWD" ] && OLDPWD=../latest cd -

...which will take you to latest and print the pathname to stdout. You can get right back where you came from by doing cd - again. You can do the same w/ $CDPATH:

mkdir -p /tmp/{1..5}  ; \
CDPATH=/tmp cd 3; cd -; \
echo "${CDPATH:-empty or unset::}" "$OLDPWD"

empty or unset:: /tmp/3
share|improve this answer
The issue does not lay in the substitution itself, it can be achieve with sed in few steps. But i don't understand why bash refuse to execute subshell, then replace its content like any other string – yabuki_joe Jan 6 at 16:07

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.