Extraire le deuxième mot d'une variable chaîne

11

J'ai une chaîne "rtcpOnNbActive true"stockée dans une variable x. Je veux extraire "true" en tant que sous-chaîne et stocker dans une variable. Comment puis-je faire ceci?

Pratibha Jain
la source
Y aura-t-il toujours un espace xjuste avant la sous-chaîne que vous souhaitez extraire?
PM 2Ring

Réponses:

21

Essayez de cette façon:

y=$(echo $x | awk '{print $2}')
echo $y
  • echo $xafficher la valeur de x.
  • awk '{print $2}'imprime le deuxième champ du précédent affiché x.
  • $(... )maintenez la sortie et laissez-la affecter y.
jherran
la source
3
echo $xn'est pas afficher la valeur dex . printf '%s\n' "$x"serait.
Stéphane Chazelas
2
awk '{print $2}'imprime le deuxième champ de chaque ligne du précédent affiché x.
Stéphane Chazelas
9

En supposant qu'il y ait au moins un espace avant la sous-chaîne que vous souhaitez extraire (et que la sous-chaîne ne contient aucun espace), vous pouvez le faire avec une simple expansion de paramètre:

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

production

[true]
PM 2Ring
la source
3
echon'est pas portable pour autre chose qu'une chaîne littérale qui ne commence pas par -et ne contient aucune séquence d'échappement. Son comportement varie même pour le module intégré bash, selon la façon dont il a été compilé et s'il XPG_ECHOest défini. En supposant que la chaîne ne contient aucune séquence d'échappement, cela devrait être bien, mais printf '[%s]\n' "$y"c'est toujours mieux.
nyuszika7h
1
@ nyuszika7h: Bon point, et après avoir lu Stéphane Chazelas dire des choses similaires ici et dans d'autres questions récentes, je dois vraiment rompre avec mon habitude d'utiliser echopour afficher la valeur des variables, même dans des exemples "jetables" comme celui-ci.
2
4

vous pouvez utiliser awk:

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

NF nombre de champs dans l'enregistrement en cours

en utilisant sed:

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

en utilisant l'expression de chaîne:

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

en utilisant grep:

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

-o est ne donne que la correspondance exacte, [a-z]+correspondra à la lettre de az et $signifie à la fin

Hackaholic
la source
2
Ne postez pas le contenu d'une autre réponse pour la vôtre dans la même question, s'il vous plaît.
αғsнιη
1
ce que les autres répondent ????
Hackaholic
il peut l'enregistrer en variable ce n'est pas un gros problème ici
Hackaholic
echon'est pas portable pour autre chose qu'une chaîne littérale qui ne commence pas par -et ne contient aucune séquence d'échappement. Son comportement varie même pour le module intégré bash, selon la façon dont il a été compilé et s'il XPG_ECHOest défini. En outre, vous devez toujours doubler les extensions de variable et la substitution de commandes (à certaines exceptions, où ce n'est pas nécessaire mais cela ne fait pas de mal non plus). Avec une chaîne comme les OP, ça devrait aller, mais si vous voulez vous assurer, ce printf '%s\n' "${a##* }"serait mieux.
nyuszika7h
3

Il est possible d'utiliser des tableaux bash pour cela, par exemple:

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

Vous pouvez utiliser la fonction readintégrée

read -r _ y <<<"$x"
printf "%s\n" "$y"
true
iruvar
la source
pourquoi impliquer read? Ce n'est pas readcela qui fait la scission - c'est le cas $IFS. Pour une raison quelconque, beaucoup de gens considèrent qu'il est acceptable de diviser w / $IFS uniquement lorsque cela readest impliqué. Vous pouvez simplement faire: set -f; IFS=' '; printf %.0s%s $xou autre chose. Dans tous les cas, vous devez spécifier $IFSla valeur de ici.
mikeserv
@mikeserv, il readfait le fractionnement en utilisant IFS, consultez la documentation . Le principal avantage de l'utilisation de read est qu'il définit des variables (ce qui est une exigence OP) et étant donné qu'il peut fractionner des chaînes et remplir un tableau, il est bon pour extraire des champs arbitraires d'une chaîne. De plus, je suppose que la valeur par défaut IFSici, mais il est assez facile à définir si nécessaire, IFS=$' \n\t' read -r _ y <<<"$x"fera l'affaire
iruvar
non ce n'est pas. readassigne, $IFSdivise. si vous voulez remplir un tableau, utilisez set- vous n'avez pas besoin du non-sens artificiel ici-chaîne dans ce cas. unset IFSobtient le comportement par défaut de $ IFS.
mikeserv
@mikeserv, vous êtes hors de ma liste de cartes de Noël.
iruvar
bah humbug. Noël est pour les drageons.
mikeserv