Какой тип операции находится в / $ / в «$ {my_array [@] / # / -}»?

17

Принятый ответ Преобразовать массив в аргументы команды? использует следующую команду Bash:

command "${my_array[@]/#/-}" "$1"

Я пытаюсь выяснить, что именно /#/-делает эта часть. К сожалению, я не знаю, как это назвать, поэтому мне сложно найти какую-либо документацию. Я просмотрел раздел справочной страницы Bash по массивам и нескольким веб-сайтам, но ничего не могу найти.

Джастин
источник

Ответы:

24

Это пример замены шаблона в расширении оболочки параметра : ${parameter/pattern/replacement}расширяется ${parameter}, заменив первый экземпляр patternс replacement. В контексте шаблона такого типа #особенность: он привязывает шаблон к началу параметра. Конечным результатом всего этого является расширение всех значений в my_arrayмассиве, добавляя -к каждому (заменяя пустой шаблон в начале каждого параметра).

Стивен Китт
источник
2

Да, это замена шаблона в расширении параметров оболочки :

${parameter/pattern/replacement}

Но если первый символ после первого /либо /или #или %оно имеет особое значение all(повторяется), startи end.

с:

$ str='one_#two_two_three_one'

Сингл /заменит первый экземпляр. Первый экземпляр one:

$ echo "${str/one/x-x}"
x-x_#two_two_three_one

Или первый экземпляр two:

$ echo "${str/two/x-x}"
one_#x-x_two_three_one

Экземпляр oneв конце:

$ echo "${str/%one/x-x}"
one_#two_two_three_x-x

Все повторения two:

$ echo "${str//two/x-x}"
one_#x-x_x-x_three_one

Экземпляр oneв начале:

$ echo "${str/#one/x-x}"
x-x_#two_two_three_one

Строка, начинающаяся с #(заключите в кавычки #):

$ echo "${str/\#two/x-x}"
one_x-x_two_three_one

Но если вы оставите # (без кавычек) в одиночестве, замена будет установлена ​​в начале переменной:

$ echo "${str/#/====}"
====one_#two_two_three_one

Кроме того, если параметр является массивом, замена выполняется для всех элементов:

$ str=( one two three )
$ echo "${str[@]/#/==}"
==one ==two ==three
Исаак
источник
Формулировка немного вводит в заблуждение, так как #и %являются частью шаблона, в то время //как оператор отличается от /и использует те же шаблоны. Вы можете иметь pattern='#x'; echo "${var/$pattern}"(или ${var//$pattern}), но pattern=/x; echo "${var/$pattern}"это не то же самое, что echo "${var//x}". Обратите внимание, что #и %могут быть объединены в zsh, но не bashни ksh.
Стефан Шазелас