Using bc to total numbers in a file

Does anyone know if it's possible to use bc() to total the numbers in a file, ie something which just has a number on every line, eg:-
Code:
27
53
77
143
 
Would it be possible add up a mix of MB and KB?
Probably not a perfect solution (I always use sed(), not awk() (-; ):
Code:
sed 's/[^0-9]*\([0-9]*\)[kK][bB]*.*/\1\*1024/; s/[^0-9]*\([0-9]*\)[mM][bB]*.*/\1\*1024^2/' my_file | bc | echo 0 `sed 's/^/+/'` | bc
However, to avoid an X-Y problem you should tell us more details on your file. In the OP you mentioned only numbers.
 
I originally thought the denominations (is that the right word) would be the same but they are a mix:-
Code:
8KB
795KB
164KB
55KB
55KB
94.50MB

I've since come across numfmt which is in GNU's coreutils, but is missing from FreeBSD's version of this.
 
Probably not a perfect solution (I always use sed(), not awk() (-; ):
Code:
sed 's/[^0-9]*\([0-9]*\)[kK][bB]*.*/\1\*1024/; s/[^0-9]*\([0-9]*\)[mM][bB]*.*/\1\*1024^2/' my_file | bc | echo 0 `sed 's/^/+/'` | bc
I like using sed(), although not clever enough for scripts like that...

When I ran this it produced
bc: stdin:1: illegal character: : unexpected
bc: stdin:1: illegal character: : unexpected
I just pasted it straight in from your post.
 
If your lines start with a digit and may contain a decimal point, the script can be improved:
Code:
sed 's/^\([0-9\.]*\)[kK][bB]*.*/\1\*1024/; s/^\([0-9\.]*\)[mM][bB]*.*/\1\*1024^2/' num | bc | echo 0 `sed 's/^/+/'` | bc
 
Code:
awk ' { s=substr($1,length($1)-1); if  (s=="GB") $1=( $1 * 1024 * 1024 ); else if (s=="MB") $1=( $1 * 1024 ); else if (s=="KB") $1= ( $1 * 1); sum += $1 } END { print sum/1024 "MB" }' myfile.txt
 
improvement of aragats' version
sed -e 's/[^0-9]*\([0-9]*\)[kK][bB]*.*/\1\*1024/; s/[^0-9]*\([0-9]*\)[mM][bB]*.*/\1\*1024^2/; s/$/+\\/' -e '$s/+\\$//' file.txt |bc
 
If you're parsing the output of du(1) keep in mind that utility will already give you a total with the -c option. Also, you won't have to worry about KB and MB suffixes if you don't use the -h option, and look at the -k option.

Edit: You might also find something like sysutils/jdiskreport useful.
 
Back
Top