Bourne / POSIX-ähnliche Shells haben einen split + glob-Operator und werden jedes Mal aufgerufen, wenn Sie eine Parametererweiterung ( $var, $-...), eine Befehlssubstitution ( $(...)) oder eine arithmetische Erweiterung ( $((...))) im Listenkontext nicht in Anführungszeichen setzen.
Eigentlich aufgerufen Sie es aus Versehen , wenn Sie tat for name in ${array[@]}statt for name in "${array[@]}". (Beachten Sie, dass das versehentliche Aufrufen dieses Operators viele Fehler und Sicherheitslücken verursacht. )
Dieser Operator wird mit dem $IFSspeziellen Parameter (um anzugeben, auf welche Zeichen aufgeteilt werden soll (wobei darauf zu achten ist, dass Leerzeichen, Tabulator und Zeilenvorschub dort eine besondere Behandlung erfahren)) und der -fOption zum Deaktivieren ( set -f) oder Aktivieren ( set +f) des globTeils konfiguriert .
Beachten Sie auch, dass das Sin $IFSursprünglich (in der Bourne-Shell, von der es $IFSstammt) für Separator war, in POSIX-Shells die Zeichen in $IFSeher als Begrenzer oder Abschlusszeichen zu sehen sind (siehe unten für ein Beispiel).
Also aufteilen _:
string='var1_var2_var3'
IFS=_ # delimit on _
set -f # disable the glob part
array=($string) # invoke the split+glob operator
for i in "${array[@]}"; do # loop over the array elements.
Um die Unterscheidung zwischen Trennzeichen und Trennzeichen zu sehen , probieren Sie Folgendes aus:
string='var1_var2_'
Das wird spaltete es in var1und var2nur (kein zusätzliches leeres Element).
Um es ähnlich wie JavaScript zu machen split(), benötigen Sie einen zusätzlichen Schritt:
string='var1_var2_var3'
IFS=_ # delimit on _
set -f # disable the glob part
temp=${string}_ # add an extra delimiter
array=($temp) # invoke the split+glob operator
(Beachten Sie, dass ein leeres Element wie bei JavaScript $stringin 1 (nicht in 0split() ) aufgeteilt wird.)
Um zu sehen, welche Sonderbehandlungen Tab, Space und Newline erhalten, vergleichen Sie:
IFS=' '; string=' var1 var2 '
(wo bekommt man var1und var2) mit
IFS='_'; string='_var1__var2__'
wo Sie bekommen: '', var1, '', var2, ''.
Beachten Sie, dass die zshShell diesen split + glob-Operator nur implizit aufruft, wenn er in shoder kshemuliert ist. Dort müssen Sie es explizit aufrufen. $=stringfür den aufgeteilten Teil, $~stringfür den Glob-Teil ( $=~stringfür beide), und es hat auch einen aufgeteilten Operator, in dem Sie das Trennzeichen angeben können:
array=(${(s:_:)string})
oder um die leeren Elemente zu erhalten:
array=("${(@s:_:)string}")
Beachten Sie, dass es szum Teilen , nicht zum Abgrenzen (auch bei $IFSeiner bekannten POSIX-Abweichung von zsh) gibt. Es unterscheidet sich von JavaScript split()darin, dass eine leere Zeichenfolge in ein 0-Element (nicht in ein 1-Element) aufgeteilt wird.
Ein bemerkenswerter Unterschied zu $IFS-splitting besteht darin, dass ${(s:abc:)string}sich die abcZeichenfolge aufteilt , während sich mit IFS=abc, das aufteilen würde a, boder c.
Mit zshund ksh93kann die Sonderbehandlung, die Leerzeichen, Tabulatoren oder Zeilenumbrüche erhalten, durch Verdoppeln entfernt werden $IFS.
Als historische Notiz hat die Bourne-Shell (die Vorgänger- oder die moderne POSIX-Shell) immer die leeren Elemente entfernt. Es hatte auch eine Reihe von Fehlern im Zusammenhang mit der Aufteilung und Erweiterung von $ @ mit Nicht-Standardwerten von $IFS. Zum Beispiel IFS=_; set -f; set -- $@wäre nicht gleichbedeutend mit IFS=_; set -f; set -- $1 $2 $3....
Aufteilen auf reguläre Ausdrücke
Wenn Sie sich etwas näher mit JavaScript befassen möchten split(), das sich in reguläre Ausdrücke aufteilen lässt, müssen Sie sich auf externe Dienstprogramme verlassen.
Hat im POSIX-Werkzeugkasten awkeinen splitOperator, der auf erweiterte reguläre Ausdrücke aufgeteilt werden kann (dies ist mehr oder weniger eine Teilmenge der von JavaScript unterstützten Perl-ähnlichen regulären Ausdrücke).
split() {
awk -v q="'" '
function quote(s) {
gsub(q, q "\\" q q, s)
return q s q
}
BEGIN {
n = split(ARGV[1], a, ARGV[2])
for (i = 1; i <= n; i++) printf " %s", quote(a[i])
exit
}' "$@"
}
string=a__b_+c
eval "array=($(split "$string" '[_+]+'))"
Die zshShell verfügt über eine integrierte Unterstützung für Perl-kompatible reguläre Ausdrücke (in ihrem zsh/pcreModul). Die Verwendung dieser Funktion zum Teilen einer Zeichenfolge ist jedoch relativ umständlich.
shellSie, mit dembashSie tun könnenIFS='_' read -a array <<< "${string}"