I have a string "rtcpOnNbActive true"
stored in a variable x
. I want to extract "true" as substring and store in a variable. How can I do this?
7 Answers
Try this way:
y=$(echo $x | awk '{print $2}')
echo $y
echo $x
display the value ofx
.awk '{print $2}'
prints the second field of the previously displayedx
.$(
...)
hold the output and let assign it toy
.
-
3
echo $x
is not display the value ofx
.printf '%s\n' "$x"
would be. Dec 13, 2014 at 9:14 -
4
awk '{print $2}'
prints the second field of each line of the previously displayedx
. Dec 13, 2014 at 9:15
Assuming that there's at least one space before the substring you wish to extract (and that the substring does not contain any spaces), you can do this with a simple parameter expansion:
x="rtcpOnNbActive true"
y="${x##* }"
echo "[$y]"
output
[true]
-
4
echo
is not portable for anything other than a literal string that doesn't start with-
and doesn't contain any escape sequences. Its behavior varies even for the bash builtin, depending on how it was compiled, and whetherXPG_ECHO
is set. Assuming the string contains no escape sequences, this should be fine, butprintf '[%s]\n' "$y"
is still better.– alexiaDec 13, 2014 at 12:59 -
1@nyuszika7h: Good point, and after having read Stéphane Chazelas say similar things here and in other recent questions I really ought to break my habit of using
echo
to display the value of variables, even in "throw-away" examples like this.– PM 2RingDec 14, 2014 at 8:00
It's possible to use bash arrays for that, just place your str
inside parenthesis. e.g.:
arr=("first second third")
echo ${arr[1]}
str="first second third"
arr1=($str)
echo ${arr1[1]}
-
2This is the best approach thanks its very simple and not an errorpron. May 12, 2021 at 7:51
-
The only sane solution. Every other solution either invokes external third-party commands that may not necessarily be available or behave as expected under the current platform (e.g.,
awk
) or performs fragile string-munging guaranteed to fail in obvious corner cases (e.g.,echo "${x##* }"
). Mar 15, 2022 at 3:56
you can use awk:
echo "rtcpOnNbActive true" | awk '{print $NF}'
true
NF
number of field in the current record
using sed:
echo "rtcpOnNbActive true" | sed 's/.* //g'
true
using string expression:
a="rtcpOnNbActive true"
echo ${a##* }
true
using grep:
echo "rtcpOnNbActive true" | grep -Eo "[a-z]+$"
true
-o is gives only exact match, [a-z]+
will match letter from a-z and $
means at end
-
3Don't post content of other answer for yours in the same question, please.– αғsнιηDec 13, 2014 at 10:09
-
1
-
-
echo
is not portable for anything other than a literal string that doesn't start with-
and doesn't contain any escape sequences. Its behavior varies even for the bash builtin, depending on how it was compiled, and whetherXPG_ECHO
is set. Also, you should always double quote variable expansions and command substitution (with certain exceptions, where it's not necessary but it doesn't do any harm either). With a string like the OP's, this should be fine, but if you want to make sureprintf '%s\n' "${a##* }"
would be better.– alexiaDec 13, 2014 at 13:03
You could use the read
built-in
read -r _ y <<<"$x"
printf "%s\n" "$y"
true
-
why involve
read
? It isn'tread
that does the split - it is$IFS
. For some reason a lot of people consider it ok to split w/$IFS
only whenread
is involved. You can just do:set -f; IFS=' '; printf %.0s%s $x
or whatever. In any case - you need to specify$IFS
's value here.– mikeservDec 14, 2014 at 1:58 -
@mikeserv, it's
read
doing the splitting usingIFS
, check the documentation. The main advantage with using read is that it sets variables (which is an OP requirement) and given that it can split strings and populate an array, is good for extracting arbitrary fields from a string. Additionally, I am assuming defaultIFS
here, but it's easy enough to set if needed,IFS=$' \n\t' read -r _ y <<<"$x"
will do the trick– iruvarDec 14, 2014 at 3:42 -
no, its not.
read
assigns,$IFS
splits. if you want to populate an array, useset
- you dont need the artificial here-string nonsense in that case.unset IFS
gets default $IFS behavior.– mikeservDec 14, 2014 at 4:57
Word splitting in bash can be accomplished very succinctly with set
builtin.
str="rtcpOnNbActive true"
# Expand positional parameters with arguments
set -- $str
# Now $1=rtcpOnNbActive and $2=true
This can be extended to a host of scenarios by altering value of IFS
variable, e.g:
ip_address="10.0.0.138"
IFS=.
set -- $ip_address
# $1=10, $2=0, $3=0, $4=138
Pretty straightforward.
x="rtcpOnNbActive true"
y=${x* }
The ${x*.} removes everything from the space forward and then assigns that value to y.
Very similar to what Hackaholic listed above, but a little more succinct.
x
just before the substring you want to extract?