I have output from the smartctl -a command; one of the lines looks like this:

9 Power_On_Hours 0x0032 100 100 000 Old_age Always - 301

I've placed this into a variable (if that's the correct term) in my bash script like this:

$SMARTCTL_OUTPUT=`smartctl -a /dev/sda`

I want to parse this so that only the number at the end of the line is returned to a variable, so in the above example 301 gets put into the variable $POWER_ON_HOURS.

I've tried using grep:

$SMARTCTL_OUTPUT=`smartctl -a /dev/sda | grep "Power_On_Hours"`

But this returns the other text (9 Power_On_Hours 0x0032 100 100 000 Old_age Always -) that I'm not interested in.

Can I return just the number at the end of the line?

  • will it always have a number on the end? echo "9 Power_On_Hours 0x0032 100 100 000 Old_age Always - 301" | awk ' { print ( $(NF) ) }' Can do the trick.
    – vfbsilva
    Aug 15, 2013 at 15:13
  • Use awk as in: $SMARTCTL_OUTPUT=$(smartctl -a /dev/sda | awk '/Power_On_Hours/{print $(10)})' I missed 9 at the beginning ;) Aug 15, 2013 at 15:14
  • Yes, the last text on the line is always a number.
    – Tim
    Aug 15, 2013 at 15:14

3 Answers 3


Using awk '{print $NF}' will do the trick. $NF refers to the last field. Awk Is a language for data extraction.

An AWK program is a series of pattern action pairs, written as:

''condition'' { ''action'' }

awk '{print $NF}'  

Will print always the last field.


You can do this with pure bash:


That returns the string resulting from removing from SMARTCTL_OUTPUT the longest prefix which does not end with a digit.


I do like gawk a lot, but you could use a more flexible approach without having to have (g)awk on your system. Store the output of your command in a bash array like this (note the back ticks around your command):

array=(`smartctl -a /dev/sda`)

Then you can refer to any word in your array by it's index number (see below for examples).

Unfortunately, I don't have devices attached to my system which "smartctl" is recognizing. So I use the output of the "man uptime" command as input for my examples.

array=(`man uptime`)

Show all elements of this array:

echo ${array[@]}
UPTIME(1) FreeBSD General Commands Manual UPTIME(1) NAME uptime — show how long system has been running SYNOPSIS uptime DESCRIPTION The uptime utility displays the current time, the length of time the sys‐ tem has been up, the number of users, and the load average of the system over the last 1, 5, and 15 minutes. FILES /boot/kernel/kernel system name list SEE O w(1) HISTORY The uptime command appeared in 3.0BSD. FreeBSD 9.1 April 18, 1994 FreeBSD 9.1

Show specific words: Please note that array elements are being counted from zero. Therefore the 7th word would be referred to as "${array[6]}".

Let's say you want to retrieve the 19th and 17th word of the output of the "man uptime" command (i.e., the words "DESCRIPTION" and "SYNOPSIS").

echo ${array[18]} ${array[16]}

Using the nifty approach from user 'Arpith' with 'read' you can also store array elements in easier to remember variables like:

read IPETH0 IPLO <<< $(echo ${array2[6]} {array2[46]}
echo $IPETH0 $IPLO

Don't mess around with something like "last field on this line" or a character mask etc. Just use position numbers.

Array indexes are positive integers. So you can do all sorts of calculations in your shell script to pick specific words (like ranges or every third word or for-loops ...)



You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .