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=$var
durchgefü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>
$var
ist in 4 args aufgeteilt.IFS
sind 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
IFS
Zeichen nicht gefunden wurden.
Nun setzen wir IFS=/
$ IFS=/
$ var="This/is/an/example"
$ showarg $var
4 args: <This> <is> <an> <example>
Das
$var
ist 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
$var
ist in 5 args aufgeteilt, nurI
am
unda
wird 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
$var
ist in 3 Args aufgeteilt.I
am\na\nmultiline
und diestring
wird gedruckt
Setzen wir den IFS auf Newline:
IFS=$'\n'
...
Nun wird der fun
ausgeführt wie:
fun 'I am' a 'multiline string'
$var
ist in 3 Args aufgeteilt.I am
,a
multiline string
wird 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'
$var
wird 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 dertest
für denI am a string with spaces
ist 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
grep
gibt 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
arr
mit 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
$packs
doppelt zitieren, wird ein Fehler ausgegeben.
Unquoetd
$packs
sendet alle durch Leerzeichen getrennten Paketnamen als Argumente anapt-get
, während die Anführungszeichen die$packs
Zeichenfolge als einzelnes Argument senden. Anschließend versuchtapt-get
, ein Paket namensapache2 php php-mbstring php-mysql
zu 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.