Zoeken…


Invoering

Het teken $ introduceert parameteruitbreiding, opdrachtvervanging of rekenkundige uitbreiding. De uit te breiden parameternaam of het symbool kan tussen accolades worden geplaatst, die optioneel zijn, maar dienen om de uit te breiden variabele te beschermen tegen tekens die er direct op volgen en die kunnen worden geïnterpreteerd als onderdeel van de naam.

Lees meer in de Bash User Manual .

Syntaxis

  • $ {parameter: offset} # Substring beginnend bij offset
  • $ {parameter: offset: length} # Substring van lengte "lengte" beginnend bij offset
  • $ {# parameter} # Lengte van de parameter
  • $ {parameter / pattern / string} # Vervang het eerste exemplaar van patroon door string
  • $ {parameter // pattern / string} # Vervang alle exemplaren van patroon door string
  • $ {parameter / # pattern / string} # Vervang patroon door string als het patroon aan het begin staat
  • $ {parameter /% pattern / string} # Vervang patroon door string als het patroon aan het einde is
  • $ {parameter # pattern} # Verwijder de kortste overeenkomst van het patroon uit het begin van de parameter
  • $ {parameter ## pattern} # Verwijder de langste overeenkomst van het patroon uit het begin van de parameter
  • $ {parameter% pattern} # Verwijder de kortste overeenkomst van patroon aan het einde van de parameter
  • $ {parameter %% pattern} # Verwijder de langste overeenkomst van het patroon aan het einde van de parameter
  • $ {parameter: -word} # Uitbreiden tot word als parameter niet ingesteld / ongedefinieerd
  • $ {parameter: = word} # Uitbreiden tot word als parameter niet ingesteld / ongedefinieerd en parameter ingesteld
  • $ {parameter: + word} # Uitbreiden tot word als parameter ingesteld / gedefinieerd

Substrings en subarrays

var='0123456789abcdef'

# Define a zero-based offset
$ printf '%s\n' "${var:3}"
3456789abcdef

# Offset and length of substring
$ printf '%s\n' "${var:3:4}"
3456
4.2
# Negative length counts from the end of the string
$ printf '%s\n' "${var:3:-5}"
3456789a

# Negative offset counts from the end
# Needs a space to avoid confusion with ${var:-6}
$ printf '%s\n' "${var: -6}"
abcdef

# Alternative: parentheses
$ printf '%s\n' "${var:(-6)}"
abcdef

# Negative offset and negative length
$ printf '%s\n' "${var: -6:-5}"
a

Dezelfde uitbreidingen zijn van toepassing als de parameter een positionele parameter of het element van een subscriptarray is :

# Set positional parameter $1
set -- 0123456789abcdef

# Define offset
$ printf '%s\n' "${1:5}"
56789abcdef

# Assign to array element
myarr[0]='0123456789abcdef'

# Define offset and length
$ printf '%s\n' "${myarr[0]:7:3}"
789

Analoge uitbreidingen zijn van toepassing op positionele parameters , waarbij offsets één zijn:

# Set positional parameters $1, $2, ...
$ set -- 1 2 3 4 5 6 7 8 9 0 a b c d e f

# Define an offset (beware $0 (not a positional parameter)
# is being considered here as well)
$ printf '%s\n' "${@:10}"
0
a
b 
c
d
e
f

# Define an offset and a length
$ printf '%s\n' "${@:10:3}"
0
a
b

# No negative lengths allowed for positional parameters
$ printf '%s\n' "${@:10:-2}"
bash: -2: substring expression < 0

# Negative offset counts from the end
# Needs a space to avoid confusion with ${@:-10:2}
$ printf '%s\n' "${@: -10:2}"
7
8

# ${@:0} is $0 which is not otherwise a positional parameters or part
# of $@
$ printf '%s\n' "${@:0:2}"
/usr/bin/bash
1

Substringuitbreiding kan worden gebruikt met geïndexeerde arrays :

# Create array (zero-based indices)
$ myarr=(0 1 2 3 4 5 6 7 8 9 a b c d e f)

# Elements with index 5 and higher
$ printf '%s\n' "${myarr[@]:12}"
c
d
e
f

# 3 elements, starting with index 5
$ printf '%s\n' "${myarr[@]:5:3}"
5
6
7

# The last element of the array
$ printf '%s\n' "${myarr[@]: -1}"
f

Lengte van parameter

# Length of a string
$ var='12345'
$ echo "${#var}"
5

Merk op dat het de lengte in aantal tekens is die niet noodzakelijkerwijs hetzelfde is als het aantal bytes (zoals in UTF-8 waar de meeste tekens in meer dan één byte zijn gecodeerd), noch het aantal glyphs / graphemes (waarvan sommige combinaties van tekens), noch is het noodzakelijkerwijs hetzelfde als de weergavebreedte.

# Number of array elements
$ myarr=(1 2 3)
$ echo "${#myarr[@]}"
3

# Works for positional parameters as well
$ set -- 1 2 3 4
$ echo "${#@}"
4

# But more commonly (and portably to other shells), one would use
$ echo "$#"
4

Het geval van alfabetische tekens wijzigen

4.0

Hoofdletters

$ v="hello"
# Just the first character
$ printf '%s\n' "${v^}"
Hello
# All characters
$ printf '%s\n' "${v^^}"
HELLO
# Alternative
$ v="hello world"
$ declare -u string="$v"
$ echo "$string"
HELLO WORLD

Naar kleine letters

$ v="BYE"
# Just the first character
$ printf '%s\n' "${v,}"
bYE
# All characters
$ printf '%s\n' "${v,,}"
bye
# Alternative
$ v="HELLO WORLD"
$ declare -l string="$v"
$ echo "$string"
hello world

Schakelkast

$ v="Hello World"
# All chars
$ echo "${v~~}"
hELLO wORLD
$ echo "${v~}"
# Just the first char
hello World

Parameterindirection

Bash indirection maakt het mogelijk om de waarde te krijgen van een variabele waarvan de naam is opgenomen in een andere variabele. Variabelen voorbeeld:

$ red="the color red"
$ green="the color green"

$ color=red
$ echo "${!color}"
the color red
$ color=green
$ echo "${!color}"
the color green

Nog enkele voorbeelden die het gebruik van indirecte expansie aantonen:

 $ foo=10
 $ x=foo
 $ echo ${x}      #Classic variable print  
 foo  
 
 $ foo=10
 $ x=foo
 $ echo ${!x}     #Indirect expansion
 10

Nog een voorbeeld:

$ argtester () { for (( i=1; i<="$#"; i++ )); do echo "${i}";done; }; argtester -ab -cd -ef 
1   #i expanded to 1 
2   #i expanded to 2
3   #i expanded to 3

$ argtester () { for (( i=1; i<="$#"; i++ )); do echo "${!i}";done; }; argtester -ab -cd -ef 
-ab     # i=1 --> expanded to $1 ---> expanded to first argument sent to function
-cd     # i=2 --> expanded to $2 ---> expanded to second argument sent to function
-ef     # i=3 --> expanded to $3 ---> expanded to third argument sent to function

Vervanging van standaardwaarde

${parameter:-word}

Als de parameter is uitgeschakeld of nul is, wordt de uitbreiding van het woord vervangen. Anders wordt de waarde van parameter vervangen.

$ unset var
$ echo "${var:-XX}"     # Parameter is unset -> expansion XX occurs
XX
$ var=""                # Parameter is null -> expansion XX occurs
$ echo "${var:-XX}"
XX
$ var=23                # Parameter is not null -> original expansion occurs
$ echo "${var:-XX}"
23
${parameter:=word}

Als de parameter is uitgeschakeld of nul is, wordt de uitbreiding van het woord toegewezen aan de parameter. De waarde van parameter wordt dan vervangen. Positieparameters en speciale parameters kunnen op deze manier niet worden toegewezen.

$ unset var
$ echo "${var:=XX}"     # Parameter is unset -> word is assigned to XX
XX
$ echo "$var"
XX
$ var=""                # Parameter is null -> word is assigned to XX
$ echo "${var:=XX}"
XX
$ echo "$var"
XX
$ var=23                # Parameter is not null -> no assignment occurs
$ echo "${var:=XX}"
23
$ echo "$var"
23

Fout als variabele leeg of uitgeschakeld is

De semantiek hiervoor is vergelijkbaar met die van standaardwaardevervanging, maar in plaats van een standaardwaarde te vervangen, loopt het fout met het opgegeven foutbericht. De formulieren zijn ${VARNAME?ERRMSG} en ${VARNAME:?ERRMSG} . Het formulier met : geeft een fout in onze als de variabele is uitgeschakeld of leeg is , terwijl het formulier zonder alleen een fout maakt als de variabele is uitgeschakeld . Als een fout wordt gegenereerd, wordt de ERRMSG uitgevoerd en wordt de ERRMSG ingesteld op 1 .

#!/bin/bash
FOO=
# ./script.sh: line 4: FOO: EMPTY
echo "FOO is ${FOO:?EMPTY}"
# FOO is 
echo "FOO is ${FOO?UNSET}"
# ./script.sh: line 8: BAR: EMPTY
echo "BAR is ${BAR:?EMPTY}"
# ./script.sh: line 10: BAR: UNSET
echo "BAR is ${BAR?UNSET}"

Het volledige voorbeeld uitvoeren boven elk van de foutieve echo-instructies moet worden uitgeschakeld om door te gaan.

Verwijder een patroon aan het begin van een string

Kortste wedstrijd:

$ a='I am a string'
$ echo "${a#*a}"
m a string

Langste wedstrijd:

$ echo "${a##*a}"
 string

Verwijder een patroon aan het einde van een string

Kortste wedstrijd:

$ a='I am a string'
$ echo "${a%a*}"
I am 

Langste wedstrijd:

$ echo "${a%%a*}"
I 

Vervang patroon in string

Eerste wedstrijd:

$ a='I am a string'
$ echo "${a/a/A}"
I Am a string

Alle wedstrijden:

$ echo "${a//a/A}"
I Am A string

Match aan het begin:

$ echo "${a/#I/y}"
y am a string

Match aan het einde:

$ echo "${a/%g/N}"
I am a strinN

Vervang een patroon door niets:

$ echo "${a/g/}"
I am a strin

Voorvoegsel toevoegen aan arrayitems:

$ A=(hello world)
$ echo "${A[@]/#/R}"
Rhello Rworld

Munging tijdens uitbreiding

Variabelen hoeven niet noodzakelijkerwijs uit te breiden naar hun waarden - substrings kunnen tijdens de uitbreiding worden geëxtraheerd, wat handig kan zijn voor het extraheren van bestandsextensies of delen van paden. Globbing karakters behouden hun gebruikelijke betekenissen, dus .* Verwijst naar een letterlijke punt, gevolgd door een willekeurige reeks karakters; het is geen reguliere uitdrukking.

$ v=foo-bar-baz
$ echo ${v%%-*}
foo
$ echo ${v%-*}
foo-bar
$ echo ${v##*-}
baz
$ echo ${v#*-}
bar-baz

Het is ook mogelijk om een variabele uit te breiden met een standaardwaarde - zeg dat ik de editor van de gebruiker wil oproepen, maar als ze er geen hebben ingesteld, zou ik ze vim willen geven.

$ EDITOR=nano
$ ${EDITOR:-vim} /tmp/some_file
# opens nano
$ unset EDITOR
$ $ ${EDITOR:-vim} /tmp/some_file
# opens vim

Er zijn twee verschillende manieren om deze uitbreiding uit te voeren, die verschillen in of de relevante variabele leeg of niet-ingesteld is. Gebruik :- gebruikt de standaardwaarde als de variabele is uitgeschakeld of leeg is, terwijl - gebruikt alleen de standaardwaarde als de variabele is uitgeschakeld, maar gebruikt de variabele als deze is ingesteld op de lege tekenreeks:

$ a="set"
$ b=""
$ unset c
$ echo ${a:-default_a} ${b:-default_b} ${c:-default_c}
set default_b default_c
$ echo ${a-default_a} ${b-default_b} ${c-default_c}
set default_c

Net als bij standaardwaarden kunnen alternatieven worden gegeven; waar een standaard wordt gebruikt als een bepaalde variabele niet beschikbaar is, wordt een alternatief gebruikt als de variabele beschikbaar is.

$ a="set"
$ b=""
$ echo ${a:+alternative_a} ${b:+alternative_b}
alternative_a

Opmerkend dat deze uitbreidingen kunnen worden genest, wordt het gebruik van alternatieven bijzonder nuttig bij het leveren van argumenten voor command line vlaggen;

$ output_file=/tmp/foo
$ wget ${output_file:+"-o ${output_file}"} www.stackexchange.com
# expands to wget -o /tmp/foo www.stackexchange.com
$ unset output_file
$ wget ${output_file:+"-o ${output_file}"} www.stackexchange.com
# expands to wget  www.stackexchange.com 

Parameteruitbreiding en bestandsnamen

U kunt Bash Parameter Expansion gebruiken om gemeenschappelijke bestandsnaam-processing operaties zoals emuleren basename en dirname .

We zullen dit gebruiken als ons voorbeeldpad:

FILENAME="/tmp/example/myfile.txt"

Om dirname te emuleren en de dirname van een bestandspad terug te geven:

echo "${FILENAME%/*}"
#Out: /tmp/example

Om basename $FILENAME te emuleren en de bestandsnaam van een bestandspad terug te geven:

echo "${FILENAME##*/}"
#Out: myfile.txt

Om basename $FILENAME .txt te emuleren en de bestandsnaam zonder .txt. uitbreiding:

BASENAME="${FILENAME##*/}"
echo "${BASENAME%%.txt}"
#Out: myfile


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow