views:

119

answers:

4

i have contents in a file

like

asdfb ... 1
adfsdf ... 2
sdfdf ..   3

I want to write a unix command that should be able to add 1 + 2 + 3 and give the result as 6

From what I am aware grep and awk would be handy, any pointers would help.

A: 

This might not exactly be what you're looking for, but I wrote a quick Ruby script to accomplish your goal:

#!/usr/bin/env ruby

total = 0
while gets
    total += $1.to_i if $_ =~ /([0-9]+)$/
end
puts total
mipadi
+1  A: 

An awk script is all you need for that, since it has grep facilities built in as part of the language.

Let's say your actual file consists of:

asdfb zz 1
adfsdf yyy 2
sdfdf xx   3

and you want to sum the third column. You can use:

echo 'asdfb zz 1
adfsdf yyy 2
sdfdf xx   3' | awk '
    BEGIN {s=0;}
          {s = s + $3;}
    END   {print s;}'

The BEGIN clause is run before processing any lines, the END clause after processing all lines.

The other clause happens for every line but you can add more clauses to change the behavior based on all sorts of things (grep-py things).

paxdiablo
It can be made to always use the last column just by changing $3 to $NF:echo 'asdfb zz 1adfsdf yyy 2sdfdf xx 3' | awk 'BEGIN {s=0;} {s = s + $NF;} END { print s;}'
Matthew Flaschen
I wanted to keep in simple, @Matthew, rather than unleash the full nuclear arsenal that is awk :-) You can pretty well do anything with it.
paxdiablo
The BEGIN clause is useless, since variables default to 0 anyway. Also no need to split this over multiple lines: awk '{s += $3} END { print s}'
Employed Russian
It may be useless to awk but not to a reader, since it shows explicit intent. The splitting across multiple lines is also for the reader. I'm a BIG fan of readable code since I've suffered much at the hands of code monkeys who couldn't format code to save their mothers life :-)
paxdiablo
+4  A: 

I believe the following is what you're looking for. It will sum up the last field in each record for the data that is read from stdin.

awk '{ sum += $NF } END { print sum }' < file.txt

Some things to note:

  1. With awk you don't need to declare variables, they are willed into existence by assigning values to them.
  2. The variable NF is the number of fields in the current record. By prepending it with a $ we are treating its value as a variable. At least this is how it appears to work anyway :)
  3. The END { } block is only once all records have been processed by the other blocks.
Bryan Kyle
A: 

Here's one in Perl.

$ cat foo.txt
asdfb ... 1
adfsdf ... 2
sdfdf ..   3

$ perl -a -n -E '$total += $F[2]; END { say $total }' foo
6

Golfed version:

perl -anE'END{say$n}$n+=$F[2]' foo
6
Hinrik