Forum: PC-Programmierung Shell: String splitten


von Informant (Gast)


Lesenswert?

wie geht das?

string="ich bin ein string"

???

echo $eins # -> ich
echo $zwei # -> bin

von Klaus W. (mfgkw)


Lesenswert?

hm, geht bestimmt auch einfacher, aber momentan bin ich etwas
phantasielos. Da fällt mir nur ein:
1
klaus@i4a:/tmp > s="abc def"; i=0; for w in $s; do a[$i]=$w; i=$(( i + 1 ));  done; echo erster ist ${a[0]}; echo zweiter ist ${a[1]}
2
erster ist abc
3
zweiter ist def

von Thomas P. (tpircher) Benutzerseite


Lesenswert?

1
string="ich bin ein string"
2
set -- $string
3
echo $1
4
echo $2
5
echo $3

HTH
Thomas

von yalu (Gast)


Lesenswert?

Wenn man die Aufrufargumente ($1, $2 usw.) nicht überschreiben möchte,
geht auch eine vereinfachte Version von Klaus' Array-Lösung (zumindest
in der Bash):
1
string="ich bin ein string"
2
3
a=($string)
4
eins=${a[0]}
5
zwei=${a[0]}
6
7
echo $eins # -> ich
8
echo $zwei # -> bin

von Klaus W. (mfgkw)


Lesenswert?

oder:
1
s="abc def"; ( echo $s | read a b ); echo erster ist $a; echo zweiter ist  $b

von yalu (Gast)


Lesenswert?

> s="abc def"; ( echo $s | read a b ); echo erster ist $a; echo zweiter ist  $b

Damit auch Strings mit mehr als zwei Wörtern (wie im Beispiel von
Informant) richtig gesplittet werden, sollte man besser
1
( echo $s | read a b dummy );

oder einfach
1
read a b dummy <<< "$s"

schreiben.

von Hc Z. (mizch)


Lesenswert?

Du solltest spezifizieren, welche Shell Du meinst.

>> s="abc def"; ( echo $s | read a b ); echo erster ist $a; echo zweiter ist  $b

ist bei einer standardkonformen (POSIX/SUSv4) Shell nichts, da der read 
selbst ohne die (unnötigen) Klammern in einer Subshell läuft und die 
nichts nach oben geben kann.

> read a b dummy <<< "$s"

Ein '<<<' kennt der Standard ebenfalls nicht.

Mit Bash z.B. werden beide Beispiele nicht funktionieren.
1
read eins zwei rest <<EOF
2
$(echo $s)
3
EOF
4
echo $zwei

sollte aber mit allen gängigen Shells klappen.

von yalu (Gast)


Lesenswert?

Hazeh Zimmerer schrieb:
>>> s="abc def"; ( echo $s | read a b ); echo erster ist $a; echo zweiter ist  $b
>
> ist bei einer standardkonformen (POSIX/SUSv4) Shell nichts, da der read
> selbst ohne die (unnötigen) Klammern in einer Subshell läuft und die
> nichts nach oben geben kann.

Stimmt.

>> read a b dummy <<< "$s"
>
> Ein '<<<' kennt der Standard ebenfalls nicht.

Ich kenne den POSIX-Standard nicht auswendig, aber die Bash mit der
Option --posix akzeptiert das '<<<' jedenfalls.

> Mit Bash z.B. werden beide Beispiele nicht funktionieren.

Die '<<<'-Variante mit der Bash 4.0.28(2)¹ schon :)

¹) wahrscheinlich auch mit deutlich älteren Versionen, die Here-Strings
   gibt es in der Bash schon sehr lange

von Klaus W. (mfgkw)


Lesenswert?

meine Variante funktioniert ebenfalls mit der bash, ich hatte
es vorher getestet und jetzt zur Sicherheit nochmals.

Gem. POSIX und mit der sh in der Tat nicht.

von Hc Z. (mizch)


Lesenswert?

1
$ s="abc def"; ( echo $s | read a b ); echo erster ist $a; echo zweiter ist  $b
2
erster ist
3
zweiter ist
4
5
$ echo $SHELL
6
/bin/bash
7
$ echo $BASH_VERSION
8
3.2.48(1)-release

Mit Version 4.0.0(3)-release dasselbe.

Es kann nicht gehen, da ein Kind (die Subshell = die Befehle in 
Klammern) nicht die Variablen seines Elternprozesses ändern kann.  Die 
Variablen der Subshell sind lokal, nach der schließenden Klammer sind 
die Variablen der Subshell wieder weg.  Ohne Klammern (sie sind 
überflüssig) würde es vermutlich in der zsh gehen, in der Bash immer 
noch nicht, da die Pipe selbst in einer Subshell ausgeführt wird.

Wenn Du ein anderes (nicht leeres) Ergebnis bekommst, sind die Variablen 
"erster" und "zweiter" evtl. durch vorheriges Experimentieren in Deiner 
Hauptshell bereits gesetzt, ihr Inhalt kann nicht von der Subshell 
kommen.

von Klaus W. (mfgkw)


Lesenswert?

ups....

ich nehme alles zurück und behaupte das Gegenteil.
Diese Version geht tatsächlich nicht!

Ich hatte es zwar probiert, aber dummerweise in  der selben Shell
wie die vorhergehende (funktionierende) Version. Von der waren
a und b noch gesetzt, wodurch das abschließende echo... etwas
ausgab.

Sorry und Danke für die hartnäckige Korrektur!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.