10

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?

  • Will there always be a space in x just before the substring you want to extract? – PM 2Ring Dec 13 '14 at 8:19
21

Try this way:

y=$(echo $x | awk '{print $2}')
echo $y
  • echo $x display the value of x.
  • awk '{print $2}' prints the second field of the previously displayed x.
  • $(...) hold the output and let assign it to y.
  • 3
    echo $x is not display the value of x. printf '%s\n' "$x" would be. – Stéphane Chazelas Dec 13 '14 at 9:14
  • 2
    awk '{print $2}' prints the second field of each line of the previously displayed x. – Stéphane Chazelas Dec 13 '14 at 9:15
9

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]
  • 3
    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 whether XPG_ECHO is set. Assuming the string contains no escape sequences, this should be fine, but printf '[%s]\n' "$y" is still better. – nyuszika7h Dec 13 '14 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 2Ring Dec 14 '14 at 8:00
4

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

  • 2
    Don't post content of other answer for yours in the same question, please. – αғsнιη Dec 13 '14 at 10:09
  • 1
    what others answers???? – Hackaholic Dec 13 '14 at 10:10
  • he can save it in variable its not a big deal here – Hackaholic Dec 13 '14 at 10:14
  • 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 whether XPG_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 sure printf '%s\n' "${a##* }" would be better. – nyuszika7h Dec 13 '14 at 13:03
3

It's possible to use bash arrays for that, e.g.:

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

You could use the read built-in

read -r _ y <<<"$x"
printf "%s\n" "$y"
true
  • why involve read? It isn't read that does the split - it is $IFS. For some reason a lot of people consider it ok to split w/ $IFS only when read 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. – mikeserv Dec 14 '14 at 1:58
  • @mikeserv, it's read doing the splitting using IFS, 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 default IFS here, but it's easy enough to set if needed, IFS=$' \n\t' read -r _ y <<<"$x" will do the trick – iruvar Dec 14 '14 at 3:42
  • no, its not. read assigns, $IFS splits. if you want to populate an array, use set - you dont need the artificial here-string nonsense in that case. unset IFS gets default $IFS behavior. – mikeserv Dec 14 '14 at 4:57
  • @mikeserv, you're off my Christmas card list. – iruvar Dec 14 '14 at 6:02
  • bah humbug. xmas is for suckers. – mikeserv Dec 16 '14 at 1:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.