I have this variable:
A="Some variable has value abc.123"
I need to extract this value i.e abc.123
. Is this possible i
How do you know where the value begins? If it's always the 5th and 6th words, you could use e.g.:
B=$(echo $A | cut -d ' ' -f 5-)
This uses the cut
command to slice out part of the line, using a simple space as the word delimiter.
Some examples using parameter expansion
A="Some variable has value abc.123"
echo "${A##* }"
abc.123
Longest match on " " space
echo "${A% *}"
Some variable has value
Longest match on . dot
echo "${A%.*}"
Some variable has value abc
Shortest match on " " space
echo "${A%% *}"
some
Read more Shell-Parameter-Expansion
Yes; this:
A="Some variable has value abc.123"
echo "${A##* }"
will print this:
abc.123
(The ${parameter##word}
notation is explained in §3.5.3 "Shell Parameter Expansion" of the Bash Reference Manual.)
Simplest is
echo $A | awk '{print $NF}'
Edit: explanation of how this works...
awk
breaks the input into different fields, using whitespace as the separator by default. Hardcoding 5
in place of NF
prints out the 5th field in the input:
echo $A | awk '{print $5}'
NF
is a built-in awk
variable that gives the total number of fields in the current record. The following returns the number 5 because there are 5 fields in the string "Some variable has value abc.123"
:
echo $A | awk '{print NF}'
Combining $
with NF
outputs the last field in the string, no matter how many fields your string contains.
As pointed out by Zedfoxus here. A very clean method that works on all Unix-based systems. Besides, you don't need to know the exact position of the substring.
A="Some variable has value abc.123"
echo $A | rev | cut -d ' ' -f 1 | rev
# abc.123
The documentation is a bit painful to read, so I've summarised it in a simpler way.
Note that the '*
' needs to swap places with the '' depending on whether you use
#
or %
. (The *
is just a wildcard, so you may need to take off your "regex hat" while reading.)
${A%% *}
- remove longest trailing *
(keep only the first word)${A% *}
- remove shortest trailing *
(keep all but the last word)${A##* }
- remove longest leading *
(keep only the last word)${A#* }
- remove shortest leading *
(keep all but the first word)Of course a "word" here may contain any character that isn't a literal space.