AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / ubuntu / 问题 / 900401
Accepted
mcExchange
mcExchange
Asked: 2017-04-06 01:40:47 +0800 CST2017-04-06 01:40:47 +0800 CST 2017-04-06 01:40:47 +0800 CST

如何从 bash 中的 ASCII 文件数据计算平均值?

  • 772

在 bash 中,我可以从这样的日志文件中 grep 一些时间测量值

grep "time:" myLogfile.txt | cut -d' ' -f 3 >> timeMeasurements.txt

#timeMeasurements.txt
2.5
3.5
2.0
...

现在我想从 中的值计算平均值timeMeasurements.txt。在 bash 中最快的方法是什么?
我知道有 gnuplot 和 R,但似乎必须为它们中的任何一个编写一些冗长的脚本。

command-line
  • 6 6 个回答
  • 1643 Views

6 个回答

  • Voted
  1. steeldriver
    2017-04-06T04:35:03+08:002017-04-06T04:35:03+08:00

    强制性GNU datamash版本

    $ datamash mean 1 < file
    2.6666666666667
    

    旁白:感觉这确实应该可以在本地实现bc(即不使用外壳或外部程序来循环输入值)。GNUbc实现包括一个read()函数——然而,让它检测输入结束似乎非常困难。我能想到的最好的是:

    #!/usr/bin/bc
    
    scale = 6
    while( (x = read()) ) {
      s += x
      c += 1
    }
    s/c
    quit
    

    然后,您可以通过管道传输文件输入,前提是您使用任何非数字字符终止输入,例如

    $ { cat file; echo '@'; } | ./mean.bc
    2.666666
    
    • 13
  2. Zanna
    2017-04-06T02:03:29+08:002017-04-06T02:03:29+08:00

    你可以使用awk. Bash 本身数学不是很好...

    awk 'BEGIN { lines=0; total=0 } { lines++; total+=$1 } END { print total/lines }' timeMeasurements.txt
    

    笔记

    • lines=0; total=0将变量设置为 0
    • lines++lines每行加一
    • total+=$1将每行中的值添加到运行总计中
    • print total/lines完成后,将总数除以值的数量
    • 12
  3. Best Answer
    Digital Trauma
    2017-04-06T09:31:45+08:002017-04-06T09:31:45+08:00

    另一种方式,使用sedand bc:

    sed 's/^/n+=1;x+=/;$ascale=1;x/n' timemeasurements.txt | bc
    

    sed 表达式将输入转换为如下形式:

    n+=1;x+=2.5
    n+=1;x+=3.5
    n+=1;x+=2.0
    scale=1;x/n
    

    这是通过管道bc逐行评估它的。

    • 11
  4. muru
    2017-04-06T02:47:13+08:002017-04-06T02:47:13+08:00

    改编此 U&L 帖子中的 R 命令:

    $ Rscript -e 'd<-scan("stdin", quiet=TRUE)' -e 'cat(mean(d), sep="\n")' < foo
    2.666667
    
    • 8
  5. Arronical
    2017-04-06T04:35:03+08:002017-04-06T04:35:03+08:00

    您可以在循环中使用bc基本计算器:whileread

    count=0; sum=0; while read -r num; do ((count++)); sum=$(echo "$sum + $num" | bc); done < timeMeasurement.txt; echo "scale=2; $sum / $count" | bc -l
    

    或者更具可读性:

    count=0
    sum=0
    while read -r num
    do
      ((count++))
      sum=$(echo "$sum + $num" | bc)
    done < timeMeasurement.txt
    echo "scale=2; $sum / $count" | bc -l
    

    解释:

    • 首先,我们将值的计数和总和设置为变量 count 和 sum,值为 0。
    • 逐行读取文件,将行中的值设置为变量num。我们使用构造while read -r num; do ... ; done < timeMeasurements.txt来做到这一点。这意味着我们将为文件的每一行做一些事情。
    • 在 while 循环中,使用 bash 算术为每一行将 count 变量加一((count++))。
    • $(...)使用带有echo管道的bash 命令替换bc将文件这一行的 num 变量的值添加到所有先前行的 num 变量的总和。bc被用作 bash 不能很好地处理浮点运算。

    至此循环结束,count变量包含时间测量值的数量,sum变量包含时间测量值的总和。

    • 与我们的变量一起使用echo来创建传递给的平均值计算bc。该scale=2部分说明bc要显示多少有效数字。
    • 5
  6. jmmut
    2017-04-07T04:39:19+08:002017-04-07T04:39:19+08:00

    datamash 似乎是一个不错的选择,但即使承认我的回答可能有点矫枉过正,以防万一你想做的不仅仅是一个平均值,octave 也不是那么冗长:

    $ octave
    octave:1> load timeMeasurements.txt 
    octave:2> mean(timeMeasurements)
    ans =  2.6667
    

    如果您使用均值,请记住相同的均值可能来自非常不同的行为,因此标准差通常也是相关的:

    octave:3> std(timeMeasurements)
    ans =  0.76376
    

    甚至一个简单的直方图也很容易做到:

    octave:4> hist(timeMeasurements)
    

    另外,我认为 datamash 不在 apt-get 存储库中以供信任,仅适用于较新版本。

    编辑:

    Oneliner,对于脚本更友好的用法:

    octave -q --eval "m = load(\"timeMeasurements.txt\"); mean(m)"
    
    • 4

相关问题

  • 如何从命令行仅安装安全更新?关于如何管理更新的一些提示

  • 如何从命令行刻录双层 dvd iso

  • 如何从命令行判断机器是否需要重新启动?

  • 文件权限如何工作?文件权限用户和组

  • 如何在 Vim 中启用全彩支持?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何运行 .sh 脚本?

    • 16 个回答
  • Marko Smith

    如何安装 .tar.gz(或 .tar.bz2)文件?

    • 14 个回答
  • Marko Smith

    如何列出所有已安装的软件包

    • 24 个回答
  • Marko Smith

    无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗?

    • 25 个回答
  • Martin Hope
    Flimm 如何在没有 sudo 的情况下使用 docker? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    Ivan 如何列出所有已安装的软件包 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    La Ode Adam Saputra 无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗? 2010-11-30 18:12:48 +0800 CST
  • Martin Hope
    David Barry 如何从命令行确定目录(文件夹)的总大小? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher “以下软件包已被保留:”为什么以及如何解决? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford 如何删除 PPA? 2010-07-30 01:09:42 +0800 CST

热门标签

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve