Parameter Substitution (Bash)
Parameter substitution, parameter expansion or shell parameter expansion means that in a Bash expression a parameter or variable is replaced by the contents of that variable, possibly in combination with an operation.
Parameter expansion is indicated by $
, often in combination with curly braces: ${}
, or even more complete: ${parameter}
.
${}
Something as simple as displaying the value of a variable is an example of parameter substitution:
$ a=12 $ echo $a 12
Adding braces might make the concept of expansion even clearer. In particular, that $
is the operator. It's not part of the variable's name: The part inside the curly braces doesn't get a $ sign:
$ a=12 $ echo ${a} 12
Not nested
You can't nest ${}
expressions: The syntax expander doesn't know how to handle them [1]. Also see below at Find & replace.
Illustration:
$ echo ${${HELLO}WORLD} -bash: ${${HELLO}WORLD}: bad substitution
${parameter:-word}
Gebruik deze syntaxis om parameter
te vervangen door literal word
als deze eerste leeg is. Zoiets als ifnull(a, b)
in SQL:
# De parameter bestaat en heeft een waarde: $ i1="Hello, world!" $ echo ${i1:-De parameter is leeg!} Hello, world!
# De parameter bestaat niet - De literal wordt weergegeven $ i1="Hello, world!" $ echo ${i3:-De parameter is leeg!} De parameter is leeg!
Wil je in plaats van een literal een parameter meegeven? Geen probleem: Daar gaat dit artikel over:
$ i1="Hello, world!" $ i2="Vervanging" $ echo ${i3:-${i2}} Vervanging
Als de parameter wel bestaat, maar leeg is:
$ i1= $ echo ${i1:-Leeg} Leeg
${parameter/pattern/string} - Find-&-replace
Parameter expansion kun je gebruiken voor find-&-replace:
$ i1="Hello, world!" $ echo ${i1/world/moon} Hello, moon!
First occurence
Standaard wordt alleen de eerste occurence van pattern vervangen:
$ i1="Hello, world1, world2 & world3!" $ echo ${i1/world/moon} Hello, moon1, world2 & world3!
Multiple occurences
Dat kun je aanpassen door pattern met een /
te laten beginnen:
$ i1="Hello, world1, world2 & world3!" $ echo ${i1//world/moon} Hello, moon1, moon2 & moon3!
Meer:
The pattern is expanded to produce a pattern just as in filename expansion. Parameter is expanded and the longest match of pattern against its value is replaced with string. The match is performed according to the rules described below (see Pattern Matching). If pattern begins with ‘/’, all matches of pattern are replaced with string. Normally only the first match is replaced. If pattern begins with ‘#’, it must match at the beginning of the expanded value of parameter. If pattern begins with ‘%’, it must match at the end of the expanded value of parameter. If string is null, matches of pattern are deleted and the / following pattern may be omitted. If the nocasematch shell option (see the description of shopt in The Shopt Builtin) is enabled, the match is performed without regard to the case of alphabetic characters. If parameter is ‘@’ or ‘*’, the substitution operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable subscripted with ‘@’ or ‘*’, the substitution operation is applied to each member of the array in turn, and the expansion is the resultant list.
Some inspiration:
- https://stackoverflow.com/questions/15116427/bash-string-replacement-gives-me-bad-substitution
- https://stackoverflow.com/questions/8960677/string-replacement-in-bash-bad-substitution-error
Mutiple substitutions
Let op: Je kunt maar één substitutie per keer toepassen: https://stackoverflow.com/questions/25996806/multiple-substitutions-on-a-string-in-bash
Convert to uppercase
[2]:
$ name="vivek" $ echo $name vivek $ echo ${name^} Vivek $ echo ${name^^} VIVEK
Casus: Extra line breaks product_cat (aug. 2021)
WordPress product_cat-taxon-beschrijvingen worden via WP-CLI en Bash bijgewerkt. Ik gebruik parameter substitution for find-&-replace, met code zoals dit:
i1=$(wp wc product_cat --user=4 get 18869 --field="description") wp wc product_cat --user=4 update 18869 --description="${i1/Alle widgets voor/All widgets for}"
Er wordt echter een karakter 0a
(line feed) toegevoegd aan het begin van de string. Hoe kan dat? Hoe verhinder ik dat?
See also
- Command substitution (Bash)
- Regular expressions (Bash)
- String comparison (Bash)
- Substring extraction (Bash)