user3576287
user3576287

Reputation: 1032

Count and sum up specific decimal number (bash,awk,perl)

I have a tab delimited file and I want to sum up certain decimal number to the output (1.5) each time its find number instead of character to the first column and print out the results for all the rows from the first to the last.

I have example file which look like this:

It has 8 rows

  1st-column 2nd-Column

  a             ship
  1             name     
  b            school
  c             book
  2             blah
  e             blah
  3             ...
  9             ...

Now I want my script to read line by line and if it finds number sum up 1.5 and give me output just for first column like this:

  0
  1.5
  1.5
  1.5
  3
  3
  4.5
  6

my script is:

  #!/bin/bash
  for c in {1..8}
  do
  awk 'NR==$c { if (/^[0-9]/) sum+=1.5} END {print sum }' file
  done

but I don't get any output!

Thanks for your help in advance.

Upvotes: 1

Views: 1611

Answers (5)

zanerock
zanerock

Reputation: 3562

Why not just use awk:

awk '{if (/^[0-9]+[[:blank:]]/) sum+=1.5} {print sum+0 }' file

Edited to simplify based on jaypal's answer, bound the number and work with tabs and spaces.

Upvotes: 2

dannysauer
dannysauer

Reputation: 3867

I'm not sure if you're multiplying the first field by 1.5 or adding 1.5 to a sum every time there's any number in $1 and ignoring the contents of the line otherwise. Here's both in awk, using your sample data as the contents of "file."

$ awk '$1~/^[0-9]+$/{val=$1*1.5}{print val+0}' file 0 1.5 1.5 1.5 3 3 4.5 9

$ awk '$1~/^[0-9]+$/{sum+=1.5}{print sum+0}' file 0 1.5 1.5 1.5 3 3 4.5 6

Or, here you go in ksh (or bash if you have a newer bash that can do floating point math), assuming the data is on STDIN

#!/usr/bin/ksh
sum=0
while read a b
do
  [[ "$a" == +([0-9]) ]] && (( sum += 1.5 ))
  print $sum
done

Upvotes: 1

jaypal singh
jaypal singh

Reputation: 77105

The last item in your expected output appears to be incorrect. If it is, then you can do:

$ awk '$1~/^[[:digit:]]+$/{sum+=1.5}{print sum+0}' file
0
1.5
1.5
1.5
3
3
4.5
6

Upvotes: 5

terdon
terdon

Reputation: 3370

How about

perl -lane 'next unless $F[0]=~/^\d+$/; $c+=1.5; END{print $c}' file 

Or

awk '$1~/^[0-9]+$/{c+=1.5}END{print c}' file 

These only produce the final sum as your script would have done. If you want to show the numbers as they grow use:

perl -lane 'BEGIN{$c=0}$c+=1.5 if $F[0]=~/^\d+$/; print "$c"' file 

Or

awk 'BEGIN{c=0}{if($1~/^[0-9]+$/){c+=1.5}{print c}}' file

Upvotes: 2

toolic
toolic

Reputation: 62037

use warnings;
use strict;

my $sum = 0;
while (<DATA>) {
    my $data = (split)[0]; # 1st column
    $sum += 1.5 if $data =~ /^\d+$/;
    print "$sum\n";
}

__DATA__
a             ship
1             name     
b            school
c             book
2             blah
e             blah
3             ...
6             ...

Upvotes: 3

Related Questions