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, nur I am und a 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 die string 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 der test für den I 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 an apt-get , während die Anführungszeichen die $packs Zeichenfolge als einzelnes Argument senden. Anschließend versucht apt-get , ein Paket namens apache2 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.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow