命令行实用程序在Linux中打印数字的统计信息

我经常发现自己的文件每行只有一个数字。 我最终将它导入Excel中查看像中位数,标准偏差等等。

有没有在Linux的命令行实用程序做同样的? 我通常需要find平均值,中值,最小值,最大值和标准偏差。

这对R来说是一件轻而易举的事情。对于一个看起来像这样的文件:

1 2 3 4 5 6 7 8 9 10 

用这个:

 R -q -e "x <- read.csv('nums.txt', header = F); summary(x); sd(x[ , 1])" 

要得到这个:

  V1 Min. : 1.00 1st Qu.: 3.25 Median : 5.50 Mean : 5.50 3rd Qu.: 7.75 Max. :10.00 [1] 3.02765 

编辑添加一些澄清评论(因为我回到这个,不记得一些理由):

  • -q标志压制R的启动许可和帮助输出
  • -e标志告诉R你将从terminal传递一个expression式
  • x是一个data.frame – 一个表,基本上。 这是一个容纳多个向量/列数据的结构,如果你只是在单个向量中读取,这是有点奇怪的。 这对您可以使用哪些function有影响。
  • 一些function,如summary() ,自然适应data.frames 。 如果x有多个字段,则summary()将为每个字段提供上述描述性统计信息。
  • sd()一次只能接受一个向量,这就是为什么我为该命令指定x[ , 1]原因( x[ , 1]返回x的第一列)。 你可以使用apply(x, MARGIN = 2, FUN = sd)来获得所有列的SD。

对于平均值,中值和标准差可以使用awk 。 例如以下将打印平均值:

 awk '{a+=$1} END{print a/NR}' myfile 

NR是logging数量的awkvariables, $1意味着该行的第一个(空格分隔的)参数( $0将是整行,在这里也可以工作,但是原则上这将是不太安全的,尽pipe对于计算它可能只是采取第一个参数), END意味着下面的命令将在处理完整个文件后执行(也可以在BEGIN{a=0}语句中将a初始化为0 ))。

对于最小/最大,你可以pipesorthead / tail

 sort -n myfile | head -n1 sort -n myfile | tail -n1 

使用“st”( https://github.com/nferraz/st

 $ st numbers.txt N min max sum mean stddev 10 1 10 55 5.5 3.02765 

要么:

 $ st numbers.txt --transpose N 10 min 1 max 10 sum 55 mean 5.5 stddev 3.02765 

(免责声明:我写这个工具:))

是的,这叫做perl
这里是简洁的一行:

 perl -e 'use List::Util qw(max min sum); @a=();while(<>){$sqsum+=$_*$_; push(@a,$_)}; $n=@a;$s=sum(@a);$a=$s/@a;$m=max(@a);$mm=min(@a);$std=sqrt($sqsum/$n-($s/$n)*($s/$n));$mid=int @a/2;@srtd=sort @a;if(@a%2){$med=$srtd[$mid];}else{$med=($srtd[$mid-1]+$srtd[$mid])/2;};print "records:$n\nsum:$s\navg:$a\nstd:$std\nmed:$med\max:$m\min:$mm";' 

 $ cat tt 1 3 4 5 6.5 7. 2 3 4 

和命令

 cat tt | perl -e 'use List::Util qw(max min sum); @a=();while(<>){$sqsum+=$_*$_; push(@a,$_)}; $n=@a;$s=sum(@a);$a=$s/@a;$m=max(@a);$mm=min(@a);$std=sqrt($sqsum/$n-($s/$n)*($s/$n));$mid=int @a/2;@srtd=sort @a;if(@a%2){$med=$srtd[$mid];}else{$med=($srtd[$mid-1]+$srtd[$mid])/2;};print "records:$n\nsum:$s\navg:$a\nstd:$std\nmed:$med\max:$m\min:$mm";' records:9 sum:35.5 avg:3.94444444444444 std:1.86256162380447 med:4 max:7. min:1 

data_hacks是用于基本统计的Python命令行工具。

从该页面的第一个例子产生所需的结果:

 $ cat /tmp/data | histogram.py # NumSamples = 29; Max = 10.00; Min = 1.00 # Mean = 4.379310; Variance = 5.131986; SD = 2.265389 # each * represents a count of 1 1.0000 - 1.9000 [ 1]: * 1.9000 - 2.8000 [ 5]: ***** 2.8000 - 3.7000 [ 8]: ******** 3.7000 - 4.6000 [ 3]: *** 4.6000 - 5.5000 [ 4]: **** 5.5000 - 6.4000 [ 2]: ** 6.4000 - 7.3000 [ 3]: *** 7.3000 - 8.2000 [ 1]: * 8.2000 - 9.1000 [ 1]: * 9.1000 - 10.0000 [ 1]: * 

Ya工具可以用来计算统计和查看分布在ASCII模式ministat 。 这是来自FreeBSD的一个工具,但是它也包含在Debian / Ubuntu等stream行的Linux发行版中。

用法示例:

 $ cat test.log Handled 1000000 packets.Time elapsed: 7.575278 Handled 1000000 packets.Time elapsed: 7.569267 Handled 1000000 packets.Time elapsed: 7.540344 Handled 1000000 packets.Time elapsed: 7.547680 Handled 1000000 packets.Time elapsed: 7.692373 Handled 1000000 packets.Time elapsed: 7.390200 Handled 1000000 packets.Time elapsed: 7.391308 Handled 1000000 packets.Time elapsed: 7.388075 $ cat test.log| awk '{print $5}' | ministat -w 74 x <stdin> +--------------------------------------------------------------------------+ | x | |xx xx xxx| | |__________________________A_______M_________________| | +--------------------------------------------------------------------------+ N Min Max Median Avg Stddev x 8 7.388075 7.692373 7.54768 7.5118156 0.11126122 

你也可以考虑使用clistats 。 这是一个高度可configuration的命令行界面工具,用于计算分隔input数字stream的统计数据。

I / O选项

  • input数据可以来自文件,标准input或pipe道
  • 输出可以写入文件,标准输出或pipe道
  • 输出使用以“#”开头的标题来启用pipe道到gnuplot

parsing选项

  • 信号,文件结束或空白行检测停止处理
  • 注释和分隔符可以设置
  • 列可以从处理中过滤掉
  • 行可以基于数字约束从处理中过滤掉
  • 行可以基于string约束从处理中过滤掉
  • 初始标题行可以被跳过
  • 固定的行数可以被处理
  • 重复的分隔符可以被忽略
  • 行可以重新排列成列
  • 严格强制只处理相同大小的行
  • 包含列标题的行可用于标题输出统计

统计选项

  • 汇总统计(计数,最小值,平均值,最大值,标准偏差)
  • 协方差
  • 关联
  • 最小二乘抵消
  • 最小平方斜率
  • 直方图
  • 过滤后的原始数据

注意:我是作者。

以防万一,有数据datastat ,一个简单的程序,用于Linux从命令行计算简单的统计数据。 例如,

 cat file.dat | datastat 

将为file.dat的每一列输出所有行的平均值。 如果您需要知道标准偏差min,max,则可以分别添加--dev ,– --min--max选项。

datastat可以根据一个或多个“键”列的值来聚合行。 例如,

 cat file.dat | datastat -k 1 

对于在第一列(“键”)上find的每个不同值,将产生所有其他列值的平均值,这些值在关键字上具有相同值的所有行中汇总。 您可以使用更多列作为关键字段(例如,-k 1-3,-k 2,4等)。

它是用C ++编写的,运行速度快,占用内存小,可以很好地与其他工具(如cutgrepsedsortawk等)配合使用。

意思:

 awk '{sum += $1} END {print "mean = " sum/NR;}' filename 

中位数:

 gawk -v max=128 ' function median(c,v, j) { asort(v,j); if (c % 2) return j[(c+1)/2]; else return (j[c/2+1]+j[c/2])/2.0; } { count++; values[count]=$1; if (count >= max) { print median(count,values); count=0; } } END { print "median = " median(count,values); }' filename 

模式:

 awk '{c[$1]++;} END {for (i in count) {if (c[i]>max) {max=i;}} print "mode = " max;}' filename 

这种模式计算需要偶数个样本,但你看它是如何工作的…

标准差:

 awk '{sum+=$1; sumsq+=$1*$1;} END {print "stdev = " sqrt(sumsq/NR - (sum/NR)**2);}' filename 
 #!/usr/bin/perl # # stdev - figure N, min, max, median, mode, mean, & std deviation # # pull out all the real numbers in the input # stream and run standard calculations on them. # they may be intermixed with other test, need # not be on the same or different lines, and # can be in scientific notion (avagadro=6.02e23). # they also admit a leading + or -. # # Tom Christiansen # tchrist@perl.com use strict; use warnings; use List::Util qw< min max >; # my $number_rx = qr{ # leading sign, positive or negative (?: [+-] ? ) # mantissa (?= [0123456789.] ) (?: # "N" or "N." or "NN" (?: (?: [0123456789] + ) (?: (?: [.] ) (?: [0123456789] * ) ) ? | # ".N", no leading digits (?: (?: [.] ) (?: [0123456789] + ) ) ) ) # abscissa (?: (?: [Ee] ) (?: (?: [+-] ? ) (?: [0123456789] + ) ) | ) }x; my $n = 0; my $sum = 0; my @values = (); my %seen = (); while (<>) { while (/($number_rx)/g) { $n++; my $num = 0 + $1; # 0+ is so numbers in alternate form count as same $sum += $num; push @values, $num; $seen{$num}++; } } die "no values" if $n == 0; my $mean = $sum / $n; my $sqsum = 0; for (@values) { $sqsum += ( $_ ** 2 ); } $sqsum /= $n; $sqsum -= ( $mean ** 2 ); my $stdev = sqrt($sqsum); my $max_seen_count = max values %seen; my @modes = grep { $seen{$_} == $max_seen_count } keys %seen; my $mode = @modes == 1 ? $modes[0] : "(" . join(", ", @modes) . ")"; $mode .= ' @ ' . $max_seen_count; my $median; my $mid = int @values/2; if (@values % 2) { $median = $values[ $mid ]; } else { $median = ($values[$mid-1] + $values[$mid])/2; } my $min = min @values; my $max = max @values; printf "n is %d, min is %g, max is %d\n", $n, $min, $max; printf "mode is %s, median is %g, mean is %g, stdev is %g\n", $mode, $median, $mean, $stdev; 

还有简单的r,它几乎可以做任何R的事情,但是用更less的击键:

https://code.google.com/p/simple-r/

要计算基本的描述性统计量,必须input以下一个:

 r summary file.txt r summary - < file.txt cat file.txt | r summary - 

对于平均值,中值,最小值,最大值和标准偏差中的每一个,代码将是:

 seq 1 100 | r mean - seq 1 100 | r median - seq 1 100 | r min - seq 1 100 | r max - seq 1 100 | r sd - 

没有得到任何简单的R!

另一个工具: https : //www.gnu.org/software/datamash/

 # Example: calculate the sum and mean of values 1 to 10: $ seq 10 | datamash sum 1 mean 1 55 5.5 

可能是更常用的包装(我发现第一个工具,至less用于nix预包装)

我发现自己想要在shellpipe道中做这件事情,为R做所有正确的争论花了一段时间。 以下是我想到的:

echo "1 2 3 4 5" | R --slave -e 'x <- scan(file="stdin",quiet=TRUE); summary(x)' Min. 1st Qu. Median Mean 3rd Qu. Max. 1 2 3 3 4 5