What type of operation is /#/- in "${my_array[@]/#/-}"?
This is an instance of pattern replacement in shell parameter expansion: ${parameter/pattern/replacement}
expands ${parameter}
, replacing the first instance of pattern
with replacement
. In the context of a pattern of this kind, #
is special: it anchors the pattern to the start of the parameter. The end result of all this is to expand all the values in the my_array
array, prepending -
to each one (by replacing the empty pattern at the start of each parameter).
Yes, it is a pattern replacement in shell parameter expansion as:
${parameter/pattern/replacement}
But if the first character after the first /
is either /
or #
or %
it has the special meaning of all
(repeated), start
and end
.
with:
$ str='one_#two_two_three_one'
A single /
will replace the first instance. The first instance of one
:
$ echo "${str/one/x-x}"
x-x_#two_two_three_one
Or the first instance of two
:
$ echo "${str/two/x-x}"
one_#x-x_two_three_one
The instance of one
at the end:
$ echo "${str/%one/x-x}"
one_#two_two_three_x-x
All repetitions of two
:
$ echo "${str//two/x-x}"
one_#x-x_x-x_three_one
The instance of one
at the start:
$ echo "${str/#one/x-x}"
x-x_#two_two_three_one
An string that start with #
(quote the #
):
$ echo "${str/\#two/x-x}"
one_x-x_two_three_one
But if you leave the # (unquoted) alone, the replacement is set at the beginning of the variable:
$ echo "${str/#/====}"
====one_#two_two_three_one
Furthermore, if the parameter is an array, the replacement is done on all elements:
$ str=( one two three )
$ echo "${str[@]/#/==}"
==one ==two ==three