Quel type d'opération est / # / - dans "$ {my_array [@] / # / -}"?


17

La réponse acceptée pour transformer un tableau en arguments d'une commande? utilise la commande Bash suivante:

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

J'essaie de comprendre /#/-exactement ce que fait la pièce. Malheureusement, je ne sais pas comment l'appeler, j'ai donc du mal à trouver de la documentation. J'ai parcouru la section de la page de manuel de Bash sur les tableaux et quelques sites Web, mais je ne trouve rien.

Réponses:


24

Il s'agit d'une instance de remplacement de modèle dans l' expansion des paramètres du shell : ${parameter/pattern/replacement}développe ${parameter}, remplaçant la première instance de patternavec replacement. Dans le cadre d'un pattern de ce type, #c'est particulier: il ancre le pattern au début du paramètre. Le résultat final de tout cela est d'étendre toutes les valeurs du my_arraytableau, en ajoutant -à chacune (en remplaçant le motif vide au début de chaque paramètre).


2

Oui, c'est un remplacement de modèle dans l' expansion des paramètres du shell comme:

${parameter/pattern/replacement}

Mais si le premier caractère après le premier /est ou /ou #ou %il a la signification spéciale de all(répété),start et end.

avec:

$ str='one_#two_two_three_one'

Un single /remplacera la première instance. La première instance de one:

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

Ou la première instance de two:

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

L'instance de one à la fin:

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

Toutes les répétitions de two :

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

L'instance de one au début:

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

Une chaîne commençant par #(citez le# ):

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

Mais si vous laissez le # (sans guillemets) seul, le remplacement est défini au début de la variable:

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

De plus, si le paramètre est un tableau, le remplacement se fait sur tous les éléments:

$ str=( one two three )
$ echo "${str[@]/#/==}"
==one ==two ==three

Le libellé est un peu trompeur car le #et %font partie du modèle tandis qu'il //est différent de l'opérateur /et utilise les mêmes modèles. Vous pouvez avoir pattern='#x'; echo "${var/$pattern}"(ou ${var//$pattern}), mais ce pattern=/x; echo "${var/$pattern}"n'est pas la même chose que echo "${var//x}". Notez que #et %peut être combiné dans zsh, mais pas dans bashni ksh.
— Stéphane Chazelas
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.