Bash
Wortaufteilung
Suche…
Syntax
- Setzen Sie IFS auf Newline: IFS = $ '\ n'
- Setzen Sie IFS auf nullstring: IFS =
- Setze IFS auf / character: IFS = /
Parameter
| Parameter | Einzelheiten |
|---|---|
| IFS | Internes Feldtrennzeichen |
| -x | Kommandos und ihre Argumente beim Ausführen drucken (Option Shell) |
Bemerkungen
- Bei Zuweisungen wird keine
newvar=$vardurchgeführt, z. B.newvar=$var - Die Wortaufteilung wird im Konstrukt
[[ ... ]]nicht ausgeführt - Verwenden Sie doppelte Anführungszeichen für Variablen, um das Teilen von Wörtern zu verhindern
Mit IFS aufteilen
Um klarer zu sein, erstellen wir ein Skript namens showarg :
#!/usr/bin/env bash
printf "%d args:" $#
printf " <%s>" "$@"
echo
Nun sehen wir die Unterschiede:
$ var="This is an example"
$ showarg $var
4 args: <This> <is> <an> <example>
$varist in 4 args aufgeteilt.IFSsind Leerzeichen, und das Wortsplitten fand daher in Leerzeichen statt
$ var="This/is/an/example"
$ showarg $var
1 args: <This/is/an/example>
In der obigen Wortaufteilung gab es keine Aufteilung, da die
IFSZeichen nicht gefunden wurden.
Nun setzen wir IFS=/
$ IFS=/
$ var="This/is/an/example"
$ showarg $var
4 args: <This> <is> <an> <example>
Das
$varist in 4 Argumente aufgeteilt, nicht in ein einzelnes Argument.
Was, wann und warum?
Wenn die Shell Parametererweiterung , Befehlssubstitution , Variablen- oder Arithmetikerweiterung durchführt , sucht sie nach Wortgrenzen im Ergebnis. Wenn eine Wortgrenze gefunden wird, wird das Ergebnis an dieser Position in mehrere Wörter aufgeteilt. Die Wortgrenze wird durch eine Shell-Variable IFS (Internal Field Separator) definiert. Die Standardwerte für IFS sind Leerzeichen, Tabulatoren und Zeilenumbrüche, dh die Wortaufteilung erfolgt bei diesen drei Leerzeichen, sofern dies nicht ausdrücklich verhindert wird.
set -x
var='I am
a
multiline string'
fun() {
echo "-$1-"
echo "*$2*"
echo ".$3."
}
fun $var
Im obigen Beispiel wird die fun Funktion so ausgeführt:
fun I am a multiline string
$varist in 5 args aufgeteilt, nurIamundawird gedruckt.
IFS & Wortaufteilung
Sehen Sie was, wann und warum, wenn Sie nicht wissen, wie IFS der Wortaufspaltung angehört
Setzen wir das IFS nur auf Leerzeichen:
set -x
var='I am
a
multiline string'
IFS=' '
fun() {
echo "-$1-"
echo "*$2*"
echo ".$3."
}
fun $var
Diese Zeitwortaufteilung funktioniert nur für Leerzeichen. Die fun Funktion wird wie folgt ausgeführt:
fun I 'am
a
multiline' string
$varist in 3 Args aufgeteilt.Iam\na\nmultilineund diestringwird gedruckt
Setzen wir den IFS auf Newline:
IFS=$'\n'
...
Nun wird der fun ausgeführt wie:
fun 'I am' a 'multiline string'
$varist in 3 Args aufgeteilt.I am,amultiline stringwird gedruckt
Mal sehen, was passiert, wenn wir IFS auf nullstring setzen:
IFS=
...
Diesmal wird der fun so ausgeführt:
fun 'I am
a
multiline string'
$varwird nicht geteilt, dh es bleibt ein einziges Argument.
Sie können das Teilen von Wörtern verhindern, indem Sie den IFS auf nullstring setzen
Ein allgemeiner Weg, um das Teilen von Wörtern zu verhindern, ist die Verwendung von Anführungszeichen:
fun "$var"
verhindert die Wortaufspaltung in allen oben diskutierten Fällen, dh die fun wird mit nur einem Argument ausgeführt.
Schlechte Auswirkungen der Wortaufspaltung
$ a='I am a string with spaces'
$ [ $a = $a ] || echo "didn't match"
bash: [: too many arguments
didn't match
[ $a = $a ]wurde interpretiert als[ I am a string with spaces = I am a string with spaces ].[ist dertestfür denI am a string with spacesist kein einzelnes Argument, sondern 6 Argumente!
$ [ $a = something ] || echo "didn't match"
bash: [: too many arguments
didn't match
[ $a = something ]wurde interpretiert als[ I am a string with spaces = something ]
$ [ $(grep . file) = 'something' ]
bash: [: too many arguments
Der Befehl
grepgibt eine mehrzeilige Zeichenfolge mit Leerzeichen zurück. Sie können sich also vorstellen, wie viele Argumente vorhanden sind ...: D
Sehen Sie was, wann und warum für die Grundlagen.
Nützlichkeit der Wortaufteilung
Es gibt einige Fälle, in denen die Wortaufteilung nützlich sein kann:
Array füllen:
arr=($(grep -o '[0-9]\+' file))
Diese füllt sich
arrmit allen numerischen Werte in der Datei gefunden
Durch das Leerzeichen getrennte Wörter:
words='foo bar baz'
for w in $words;do
echo "W: $w"
done
Ausgabe:
W: foo
W: bar
W: baz
Durch Leerzeichen getrennte Parameter, die keine Leerzeichen enthalten:
packs='apache2 php php-mbstring php-mysql'
sudo apt-get install $packs
oder
packs='
apache2
php
php-mbstring
php-mysql
'
sudo apt-get install $packs
Dadurch werden die Pakete installiert. Wenn Sie die
$packsdoppelt zitieren, wird ein Fehler ausgegeben.
Unquoetd
$packssendet alle durch Leerzeichen getrennten Paketnamen als Argumente anapt-get, während die Anführungszeichen die$packsZeichenfolge als einzelnes Argument senden. Anschließend versuchtapt-get, ein Paket namensapache2 php php-mbstring php-mysqlzu installieren.apache2 php php-mbstring php-mysql(für den ersten), der offensichtlich nicht existiert
Sehen Sie was, wann und warum für die Grundlagen.
Teilen durch Trennzeichenänderungen
Wir können einfach Trennungen vom Leerzeichen in eine neue Zeile ersetzen, wie im folgenden Beispiel.
echo $sentence | tr " " "\n"
Es teilt den Wert des variablen sentence und zeigt ihn Zeile für Zeile.