macoszsh

What does this {} and // do in this command on Mac?


Recently, I found a cool trick that helps replace a substring in an environment variable with another substring. But I don't really understand how it does it.

TEST_URL="abc/123.com"
NEW_TEST_URL="${TEST_URL/123/123-ro-}"
echo $NEW_TEST_URL

Now NEW_TEST_URL is abc/123-ro-.com

This // looks similar to the substitute command.

I ran this on a Mac terminal

echo $0 returns -zsh


Solution

  • You can find an explanation in man zshexpn manpage:

    ${name/pattern/repl}
    ${name//pattern/repl}
    ${name:/pattern/repl}
    
           Replace the longest possible match of pattern in the
           expansion of parameter name by string repl.  The first form
           replaces just the first occurrence, the second form all
           occurrences, and the third form replaces only if pattern
           matches the entire string.  Both pattern and repl are
           subject to double-quoted substitution, so that expressions
           like ${name/$opat/$npat} will work, but obey the usual rule
           that pattern characters in $opat are not treated specially
           unless either the option GLOB_SUBST is set, or $opat is
           instead substituted as ${~opat}.
    
           The pattern may begin with a `#', in which case the pattern
           must match at the start of the string, or `%', in which
           case it must match at the end of the string, or `#%' in
           which case the pattern must match the entire string.  The
           repl may be an empty string, in which case the final `/'
           may also be omitted.  To quote the final `/' in other cases
           it should be preceded by a single backslash; this is not
           necessary if the `/' occurs inside a substituted parameter.
           Note also that the `#', `%' and `#% are not active if they
           occur inside a substituted parameter, even at the start.
    
           If, after quoting rules apply, ${name} expands to an array,
           the replacements act on each element individually.  Note
           also the effect of the I and S parameter expansion flags
           below; however, the flags M, R, B, E and N are not useful.
    
           For example,
    
                  foo="twinkle twinkle little star" sub="t*e" rep="spy"
                  print ${foo//${~sub}/$rep}
                  print ${(S)foo//${~sub}/$rep}
    
           Here, the `~' ensures that the text of $sub is treated as a
           pattern rather than a plain string.  In the first case, the
           longest match for t*e is substituted and the result is `spy
           star', while in the second case, the shortest matches are
           taken and the result is `spy spy lispy star