简体   繁体   中英

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.

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

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

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM