Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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?

share|improve this question
    
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 '13 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 ;) –  val0x00ff Aug 15 '13 at 15:14
    
Yes, the last text on the line is always a number. –  Tim Aug 15 '13 at 15:14
add comment

3 Answers

up vote 3 down vote accepted

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.

share|improve this answer
add comment

You can do this with pure bash:

POWER_ON_HOURS=${SMARTCTL_OUTPUT##[^0-9]}

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

share|improve this answer
add comment

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]}
DESCRIPTION SYNOPSIS

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

array2=(`ifconfig`)
read IPETH0 IPLO <<< $(echo ${array2[6]} {array2[46]}
echo $IPETH0 $IPLO
192.168.0.103 127.0.0.1

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 ...)

HTH

bernie

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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