Welche Art von Operation ist / # / - in "$ {my_array [@] / # / -}"?

17

Die akzeptierte Antwort, um ein Array in Argumente eines Befehls umzuwandeln? verwendet den folgenden Bash-Befehl:

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

Ich versuche herauszufinden, was der /#/-Teil genau macht. Leider weiß ich nicht, wie ich es nennen soll, daher habe ich Probleme, Unterlagen zu finden. Ich habe den Manpage-Bereich von Bash auf Arrays und einigen Websites durchgesehen, kann aber nichts finden.

Justin
quelle

Antworten:

24

Dies ist ein Beispiel des Musteraustausches in Schalenparameter Expansion : ${parameter/pattern/replacement}ausdehnt ${parameter}, die erste Instanz des Ersetzen patternmit replacement. Im Zusammenhang mit einem Muster dieser Art #ist besonders: Es verankert das Muster am Anfang des Parameters. Das Endergebnis all dessen besteht darin, alle Werte im my_arrayArray vor jedem -einzelnen zu erweitern (indem das leere Muster am Anfang jedes Parameters ersetzt wird).

Stephen Kitt
quelle
2

Ja, es handelt sich um eine Musterersetzung bei der Shell-Parametererweiterung als:

${parameter/pattern/replacement}

Aber wenn das erste Zeichen nach dem ersten /entweder /oder ist #oder %die spezielle Bedeutung von all(wiederholt) startund hat end.

mit:

$ str='one_#two_two_three_one'

Eine einzelne /wird die erste Instanz ersetzen. Die erste Instanz von one:

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

Oder die erste Instanz von two:

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

Die Instanz von oneam Ende:

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

Alle Wiederholungen von two:

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

Die Instanz von onezu Beginn:

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

Eine Zeichenfolge, die mit #(Anführungszeichen #) beginnt :

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

Wenn Sie jedoch das # (ohne Anführungszeichen) in Ruhe lassen, wird die Ersetzung am Anfang der Variablen festgelegt:

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

Wenn der Parameter ein Array ist, erfolgt die Ersetzung außerdem für alle Elemente:

$ str=( one two three )
$ echo "${str[@]/#/==}"
==one ==two ==three
Isaac
quelle
Der Wortlaut ist etwas irreführend, da #und %Teil des Musters sind, während //ein anderer Operator /als die gleichen Muster verwendet wird. Sie können haben pattern='#x'; echo "${var/$pattern}"(oder ${var//$pattern}), ist aber pattern=/x; echo "${var/$pattern}"nicht dasselbe wie echo "${var//x}". Beachten Sie, dass #und %in zsh, aber nicht bashnoch kombiniert werden können ksh.
Stéphane Chazelas