Bash
Bash-Parametererweiterung
Suche…
Einführung
Das $
-Zeichen führt die Parametererweiterung, Befehlssubstitution oder Arithmetikerweiterung ein. Der Parametername oder das Symbol, das erweitert werden soll, kann in geschweifte Klammern eingeschlossen werden. Diese sind optional, dienen jedoch dem Schutz der zu erweiternden Variablen vor unmittelbar darauf folgenden Zeichen, die als Teil des Namens interpretiert werden könnten.
Lesen Sie mehr im Bash-Benutzerhandbuch .
Syntax
- $ {parameter: offset} # Teilstring beginnt mit dem Offset
- $ {Parameter: Offset: Länge} # Teilzeichenfolge der Länge "Länge" ab Offset
- $ {# parameter} # Länge des Parameters
- $ {parameter / pattern / string} # Ersetzt das erste Vorkommen von Pattern durch String
- $ {parameter // pattern / string} # Ersetzen Sie alle Vorkommen von Pattern durch String
- $ {parameter / # pattern / string} # Ersetzen Sie das Muster durch den String, wenn das Muster am Anfang steht
- $ {parameter /% pattern / string} # Ersetzen Sie das Muster durch den String, wenn sich das Muster am Ende befindet
- $ {parameter # pattern} # Entfernt die kürzeste Übereinstimmung des Musters vom Anfang des Parameters
- $ {parameter ## pattern} # Entfernt die längste Übereinstimmung des Musters vom Anfang des Parameters
- $ {parameter% pattern} # Entfernt die kürzeste Übereinstimmung des Musters vom Ende des Parameters
- $ {parameter %% pattern} # Entfernt die längste Übereinstimmung des Musters vom Parameterende
- $ {parameter: -word} # Erweitern Sie das Wort, wenn der Parameter nicht festgelegt bzw. nicht definiert ist
- $ {parameter: = word} # Erweitern Sie sich auf word, wenn der Parameter nicht gesetzt / undefined ist, und setzen Sie den Parameter
- $ {parameter: + word} # Bei Wort erweitern / erweitern, wenn Parameter gesetzt / definiert sind
Substrings und 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
# 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
Die gleichen Erweiterungen gelten, wenn der Parameter ein Positionsparameter oder das Element eines subskribierten Arrays ist :
# 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 Erweiterungen gelten für Positionsparameter , bei denen die Offsets eins sind:
# 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
Substring-Erweiterung kann mit indizierten Arrays verwendet werden :
# 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
Länge des Parameters
# Length of a string
$ var='12345'
$ echo "${#var}"
5
Beachten Sie, dass die Länge der Zeichenanzahl nicht unbedingt gleich der Anzahl der Bytes ist (wie in UTF-8, wo die meisten Zeichen in mehr als einem Byte codiert sind) oder der Anzahl der Glyphen / Grapheme (von denen einige sind) Zeichenkombinationen), und ist nicht notwendigerweise mit der Anzeigebreite identisch.
# 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
Fall von alphabetischen Zeichen ändern
Zu Großbuchstaben
$ 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
Kleinschreibung
$ 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
Fall umschalten
$ v="Hello World"
# All chars
$ echo "${v~~}"
hELLO wORLD
$ echo "${v~}"
# Just the first char
hello World
Parameter-Indirektion
Bash
Indirektion erlaubt es, den Wert einer Variablen abzurufen, deren Name in einer anderen Variablen enthalten ist. Beispiel für Variablen:
$ red="the color red"
$ green="the color green"
$ color=red
$ echo "${!color}"
the color red
$ color=green
$ echo "${!color}"
the color green
Einige weitere Beispiele, die die Verwendung der indirekten Erweiterung demonstrieren:
$ foo=10
$ x=foo
$ echo ${x} #Classic variable print
foo
$ foo=10
$ x=foo
$ echo ${!x} #Indirect expansion
10
Noch ein Beispiel:
$ 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
Standardwertersetzung
${parameter:-word}
Wenn der Parameter unset oder null ist, wird die Erweiterung des Wortes verwendet. Andernfalls wird der Wert des Parameters ersetzt.
$ 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}
Wenn der Parameter unset oder null ist, wird die Erweiterung des Wortes dem Parameter zugewiesen. Der Wert des Parameters wird dann ersetzt. Positionsparameter und Sonderparameter dürfen auf diese Weise nicht zugewiesen werden.
$ 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
Fehler, wenn Variable leer oder nicht gesetzt ist
Die Semantik hierfür ähnelt derjenigen der Standardwertersetzung, aber anstelle eines Standardwerts wird ein Fehler mit der bereitgestellten Fehlermeldung ausgegeben. Die Formulare lauten ${VARNAME?ERRMSG}
und ${VARNAME:?ERRMSG}
. Das Formular mit :
unser Fehler , wenn die Variable nicht gesetzt oder leer ist, während die Form ohne nur aus wird Fehler , wenn die Variable nicht gesetzt ist. Wenn ein Fehler ausgelöst wird, wird das ERRMSG
ausgegeben und der ERRMSG
auf 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}"
Das vollständige Beispiel oberhalb der fehlerhaften Echoanweisungen muss ausgeführt werden, um fortfahren zu können.
Löschen Sie ein Muster vom Anfang einer Zeichenfolge
Kürzeste Übereinstimmung:
$ a='I am a string'
$ echo "${a#*a}"
m a string
Längste Übereinstimmung:
$ echo "${a##*a}"
string
Löschen Sie ein Muster vom Ende einer Zeichenfolge
Kürzeste Übereinstimmung:
$ a='I am a string'
$ echo "${a%a*}"
I am
Längste Übereinstimmung:
$ echo "${a%%a*}"
I
Ersetzen Sie das Muster in der Zeichenfolge
Erstes Spiel:
$ a='I am a string'
$ echo "${a/a/A}"
I Am a string
Alle Spiele:
$ echo "${a//a/A}"
I Am A string
Spiel am Anfang:
$ echo "${a/#I/y}"
y am a string
Spiel am Ende:
$ echo "${a/%g/N}"
I am a strinN
Ersetzen Sie ein Muster durch nichts:
$ echo "${a/g/}"
I am a strin
Präfix zu Array-Elementen hinzufügen:
$ A=(hello world)
$ echo "${A[@]/#/R}"
Rhello Rworld
Munging während der Expansion
Variablen müssen nicht unbedingt auf ihre Werte erweitert werden - Teilstrings können während der Erweiterung extrahiert werden, was zum Extrahieren von Dateierweiterungen oder Teilen von Pfaden nützlich sein kann. Globbing-Zeichen behalten ihre üblichen Bedeutungen, daher bezieht sich .*
auf einen wörtlichen Punkt, gefolgt von einer beliebigen Zeichenfolge; Es ist kein regulärer Ausdruck.
$ v=foo-bar-baz
$ echo ${v%%-*}
foo
$ echo ${v%-*}
foo-bar
$ echo ${v##*-}
baz
$ echo ${v#*-}
bar-baz
Es ist auch möglich, eine Variable mit einem Standardwert zu erweitern - zum Beispiel, ich möchte den Editor des Benutzers aufrufen, aber wenn sie nicht festgelegt wurden, möchte ich ihnen einen vim
.
$ EDITOR=nano
$ ${EDITOR:-vim} /tmp/some_file
# opens nano
$ unset EDITOR
$ $ ${EDITOR:-vim} /tmp/some_file
# opens vim
Es gibt zwei verschiedene Arten, diese Erweiterung durchzuführen, die sich darin unterscheiden, ob die relevante Variable leer oder nicht gesetzt ist. Using :-
verwendet den Standardwert, wenn die Variable entweder nicht festgelegt oder leer ist, während -
der Standardwert nur verwendet wird, wenn die Variable nicht festgelegt ist;
$ 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
Ähnlich wie bei den Standardwerten können Alternativen angegeben werden. Wird ein Standardwert verwendet, wenn eine bestimmte Variable nicht verfügbar ist, wird eine Alternative verwendet, wenn die Variable verfügbar ist.
$ a="set"
$ b=""
$ echo ${a:+alternative_a} ${b:+alternative_b}
alternative_a
Beachten Sie, dass diese Erweiterungen verschachtelt werden können. Die Verwendung von Alternativen ist besonders nützlich, wenn Argumente für Befehlszeilenflags angegeben werden.
$ 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
Parametererweiterung und Dateinamen
Sie können Bash Parameter Expansion verwenden , um gemeinsame Dateinamen-Verarbeitungsoperationen wie zu emulieren basename
und dirname
.
Wir werden dies als Beispielpfad verwenden:
FILENAME="/tmp/example/myfile.txt"
Zu emulieren dirname
und gibt den Verzeichnisnamen eines Dateipfad:
echo "${FILENAME%/*}"
#Out: /tmp/example
So emulieren Sie den basename $FILENAME
und geben den Dateinamen eines Dateipfads zurück:
echo "${FILENAME##*/}"
#Out: myfile.txt
Um den basename $FILENAME .txt
zu emulieren und den Dateinamen ohne die basename $FILENAME .txt
zurückzugeben .txt.
Erweiterung:
BASENAME="${FILENAME##*/}"
echo "${BASENAME%%.txt}"
#Out: myfile