Extrahieren des zweiten Wortes aus einer Zeichenfolgenvariablen

11

Ich habe eine Zeichenfolge "rtcpOnNbActive true"in einer Variablen gespeichert x. Ich möchte "true" als Teilzeichenfolge extrahieren und in einer Variablen speichern. Wie kann ich das machen?

Pratibha Jain
quelle
Wird es immer ein Leerzeichen xkurz vor dem Teilstring geben, den Sie extrahieren möchten?
PM 2Ring

Antworten:

21

Versuchen Sie Folgendes:

y=$(echo $x | awk '{print $2}')
echo $y
  • echo $xZeigen Sie den Wert von an x.
  • awk '{print $2}'druckt das zweite Feld des zuvor angezeigten x.
  • $(... )halten Sie den Ausgang und lassen Sie ihn zuweisen y.
jherran
quelle
3
echo $xzeigt nicht den Wert von anx . printf '%s\n' "$x"wäre.
Stéphane Chazelas
2
awk '{print $2}'druckt das zweite Feld jeder Zeile der zuvor angezeigten x.
Stéphane Chazelas
9

Angenommen, vor dem zu extrahierenden Teilstring befindet sich mindestens ein Leerzeichen (und der Teilstring enthält keine Leerzeichen), können Sie dies mit einer einfachen Parametererweiterung tun:

x="rtcpOnNbActive     true"
y="${x##* }"
echo "[$y]"

Ausgabe

[true]
PM 2Ring
quelle
3
echoist für nichts anderes als eine Literalzeichenfolge portierbar, die nicht mit beginnt -und keine Escape-Sequenzen enthält. Das Verhalten variiert sogar für das eingebaute Bash, je nachdem, wie es kompiliert wurde und ob XPG_ECHOes eingestellt ist. Angenommen, die Zeichenfolge enthält keine Escape-Sequenzen, sollte dies in Ordnung sein, ist aber printf '[%s]\n' "$y"immer noch besser.
Nyuszika7h
1
@ nyuszika7h: Guter Punkt, und nachdem ich gelesen habe, dass Stéphane Chazelas hier und in anderen aktuellen Fragen ähnliche Dinge gesagt hat, sollte ich wirklich meine Gewohnheit aufgeben echo, den Wert von Variablen anzuzeigen, selbst in solchen "Wegwerf" -Beispielen.
PM 2Ring
4

Sie können awk verwenden:

echo "rtcpOnNbActive         true" | awk '{print $NF}'
true

NF Anzahl der Felder im aktuellen Datensatz

mit sed:

echo "rtcpOnNbActive         true" | sed 's/.* //g'
true

Verwenden des Zeichenfolgenausdrucks:

 a="rtcpOnNbActive         true"
 echo ${a##* }
 true

mit grep:

 echo "rtcpOnNbActive         true" | grep -Eo "[a-z]+$"
 true

-o gibt nur exakte Übereinstimmung, [a-z]+stimmt mit Buchstaben von az überein und $bedeutet am Ende

Hackaholic
quelle
2
Veröffentlichen Sie bitte keine Inhalte anderer Antworten für Sie in derselben Frage.
αғsнιη
1
was andere antworten ????
Hackaholic
er kann es in variablen speichern, es ist keine große Sache hier
Hackaholic
echoist für nichts anderes als eine Literalzeichenfolge portierbar, die nicht mit beginnt -und keine Escape-Sequenzen enthält. Das Verhalten variiert sogar für das eingebaute Bash, je nachdem, wie es kompiliert wurde und ob XPG_ECHOes eingestellt ist. Außerdem sollten Sie Variablenerweiterungen und Befehlssubstitutionen immer in doppelte Anführungszeichen setzen (mit bestimmten Ausnahmen, bei denen dies nicht erforderlich ist, aber auch keinen Schaden anrichtet). Mit einer Zeichenfolge wie den OPs sollte dies in Ordnung sein, aber wenn Sie sicherstellen printf '%s\n' "${a##* }"möchten , wäre dies besser.
Nyuszika7h
3

Es ist möglich, dafür Bash-Arrays zu verwenden, z.

arr="(first second third)"
echo ${arr[1]}
Kenorb
quelle
2

Sie könnten das readeingebaute verwenden

read -r _ y <<<"$x"
printf "%s\n" "$y"
true
iruvar
quelle
warum einbeziehen read? Es ist nicht so, readdass die Trennung erfolgt - es ist so $IFS. Aus irgendeinem Grund halten es viele Leute für in Ordnung, sich $IFS nur dann zu trennen, wenn reades darum geht. Sie können einfach tun: set -f; IFS=' '; printf %.0s%s $xoder was auch immer. In jedem Fall müssen Sie $IFShier den Wert angeben .
Mikesserv
@mikeserv, es readmacht die Aufteilung mit IFS, überprüfen Sie die Dokumentation . Der Hauptvorteil bei der Verwendung von read besteht darin, dass Variablen festgelegt werden (was eine OP-Anforderung ist). Da es Zeichenfolgen aufteilen und ein Array füllen kann, eignet es sich zum Extrahieren beliebiger Felder aus einer Zeichenfolge. Außerdem gehe ich IFShier von einer Standardeinstellung aus, aber es ist einfach genug, diese bei Bedarf IFS=$' \n\t' read -r _ y <<<"$x"
festzulegen. Sie
Nein, ist es nicht. readweist zu, $IFSteilt. Wenn Sie ein Array setfüllen möchten, verwenden Sie - in diesem Fall benötigen Sie keinen künstlichen Unsinn. unset IFSRuft das Standardverhalten von $ IFS ab.
Mikesserv
@mikeserv, du bist von meiner Weihnachtskartenliste gestrichen.
iruvar
bah humbug. Weihnachten ist für Trottel.
Mikeserv