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 run the following command:

grep -o "[0-9] errors" verification_report_3.txt | awk '{print $1}'

and I get the following result:

1
4
0
8

I'd like to add each of the numbers up to a running count variable. Is there a magic one liner someone can help me build?

share|improve this question

5 Answers 5

up vote 13 down vote accepted
grep -o "[0-9] errors" verification_report_3.txt | awk '{ SUM += $1} END { print SUM }'

That doesn't print the list but does print the sum. If you want both the list and the sum, you can do:

grep -o "[0-9] errors" verification_report_3.txt | awk '{ SUM += $1; print $1} END { print SUM }'
share|improve this answer
    
Shawn - thank you for your answer. How do I return total back to the bash script out of awk? –  Amir Afghani Dec 14 '10 at 21:28
2  
@Amir You would use the first one like this variable=$(grep -o "[0-9] errors" verification_report_3.txt | awk '{ SUM += $1} END { print SUM }') This puts the output of the command (which is only the sum value) into the variable called variable –  Shawn J. Goff Dec 14 '10 at 21:33
2  
@Amir Afghani Also, you might want to change your grep to "[0-9]\+ errors". This will match if you have a line reporting >9 errors. –  Shawn J. Goff Dec 14 '10 at 21:36
    
Yup, wow I can't believe I missed that. Thank you. –  Amir Afghani Dec 14 '10 at 21:43
    
Shawn, the output seems like it's not adding up my results. It looks like this: Total Errors = +259+7581+8852+2014+3189++13572+11438+++6+4172+ –  Amir Afghani Dec 14 '10 at 21:58

This can all be done in awk as well:

awk '"[0-9]+ errors" {sum += $1}; END {print sum}' verification_report_3.txt
share|improve this answer

You appear to be using GNU system, so if Perl regular expressions support is available, you could write something like this:

grep -Po '[0-9]+(?=\s+errors)' infile | 
  paste -sd+ | 
    bc

P.S. I modified the regular expression (added the + quantifier) to allow numbers > 9.

P.S. Alternatively, awk is sufficient (assuming GNU awk):

awk 'END { print s }
/[0-9]+[[:space:]]+errors/ { 
  s += $1 
  }' infile
share|improve this answer

Try piping the output from your grep into

awk 'BEGIN {total=0;}{total+=$1;}END {print "Total: ",total}'
share|improve this answer

I use this:

$ echo $(cat file | sed 's/$/+/') 0 | bc

It isn't efficient for large lists, but for most of my use cases it is fine. I usually use a shell function to automate the process so that I only have to provide a file name:

## cheezy summation
##   call from .bashrc
##
getsum () { echo $(cat $1 | sed 's/$/+/') 0 | bc; }
gethsum () { echo $(cat $1 | sed 's/[gG]/*1000M/' | sed 's/[mM]/*1000K/' | sed 's/[kK]/*1000/' | sed 's/$/+/') 0 | bc; }
gethexsum () { echo ibase=16 $(cat $1 | sed 's/$/+/') 0 | bc; }

You can always substitute the end-of-line marker for a specific element separator or character class if your data is delimited in another fashion.

share|improve this answer

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.