Short answer? It turns out you can do lots of manipulations with variables beyone simply inserting them like you would with $PWD
. Quoting from the bash reference manual:
${parameter/pattern/string}
The pattern is expanded to produce a pattern just as in filename expansion. Parameter is expanded and the longest match of pattern against its value is replaced with string. If pattern begins with ‘/
’, all matches of pattern are replaced with string. Normally only the first match is replaced. If pattern begins with ‘#
’, it must match at the beginning of the expanded value of parameter. If pattern begins with ‘%
’, it must match at the end of the expanded value of parameter. If string is null, matches of pattern are deleted and the /
following pattern may be omitted. If parameter is ‘@
’ or ‘*
’, the substitution operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable subscripted with ‘@
’ or ‘*
’, the substitution operation is applied to each member of the array in turn, and the expansion is the resultant list.
So, in this example: ${PWD/\/$upto\/*//$upto}
- parameter is
PWD
.
- pattern is
/$upto/*
(that's what the backslashes are for, to keep the slashes in pattern from ending the pattern prematurely, and to avoid turning on the "replace all matches" behavior you'd normally get from a pattern that starts with a slash)
- string is
/$upto
So this looks in the variable $PWD
(which the shell maintains as the current directory), finds the first spot in there where there's the directory name that's in $upto
surrounded by slashes (so that setting $upto
to "dog
" won't find a directory named "dogfood
"), and replaces that spot and the whole rest of the current directory by just "/$upto
".
$upto
.