简体   繁体   English

计算并汇总特定的十进制数字(bash,awk,perl)

[英]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. 我有一个制表符分隔的文件,我想在输出(1.5)每次找到数字时都将某个十进制数字求和,而不是将字符排到第一列,并打印出从第一行到最后一行的所有行的结果。

I have example file which look like this: 我有看起来像这样的示例文件:

It has 8 rows 它有8行

  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: 现在,我希望我的脚本逐行读取,如果它发现数字总和为1.5,则只为第一列提供输出,如下所示:

  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:

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. 根据jaypal的答案进行了简化编辑,限制了数字并使用制表符和空格。

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. 我不确定每次$ 1中是否有任何数字时,是否要将第一个字段乘以1.5或将1.5加到总和上,否则忽略该行的内容。 Here's both in awk, using your sample data as the contents of "file." 这都是awk,使用示例数据作为“文件”的内容。

$ 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 或者,假设数据在STDIN上,则在这里使用ksh(或者bash(如果您有更新的bash可以执行浮点数学运算))

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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