用于计算两个不同子集中列之间平均值的Shell脚本

时间:2013-09-24 10:35:52

标签: linux shell awk

我有一些特别讨厌的shell编程,只需要很少的shell脚本编写经验。我有以下文本文件。我需要做的是计算子集1的平均Y(m)和子集2的平均Y(m)之间的差异。可以有两个以上的子集,但它足以计算子集之间的差异1和子集2.

我尝试过各种各样的awk命令,但似乎我的大脑因为太多的障碍而被炸掉了。 Arghhh!

MODEL PARAMETERS :
Project : Report
Dataset : xxx

Number of subsets    : 2
Total number         : 8

Subset number    : 1
Subset name      : xxx_sub1
Number           : 4

 NR   TYPE                       X(m)      Y(m)    Z(m)   Volume Pressure   CluNo     Activ  Group
 ---  ---------------------    ------    ------   -----  ------- --------   -----     -----  ------
   1  Type text                  0.00    -10.40    9.00   2000.0    500.0       0     0     1
   2  Type text                  0.00     -9.60    9.00   1000.0    500.0       0     1     1
   3  Type text                  3.00    -10.40    9.00   1200.0    500.0       1     1     1
   4  Type text                  3.00     -9.60    9.00    800.0    500.0       1     1     1

Subset number    : 2
Subset name      : xxx_sub2
Number           : 4

 NR   TYPE                       X(m)      Y(m)    Z(m)   Volume Pressure   CluNo Activ  Group
 ---  ---------------------    ------    ------   -----  ------- --------   ----- -----  ------
   1  Type text                  0.00     10.40   15.00   2000.0    500.0       0         0     1
   2  Type text                  0.00      9.60   15.00   1000.0    500.0       0     1     1
   3  Type text                  3.00     10.40   15.00   1200.0    500.0       1     1     1
   4  Type text                  3.00      9.60   15.00    800.0    500.0       1     1     1

Units : 
   Coordinates      : meter
   Volume           : cubic cm
   Pressure         : pascal

基本上我需要第一组Y(m)值的平均值:( - 10.4-9.6-10.4-9.6)/ 4 = -10m和第二组Y(m)值的平均值(10.4+) 9.6 + 10.4 + 9.6)/ 4 = 10m并计算两个平均值之间的差值,即20m。

2 个答案:

答案 0 :(得分:4)

可以使用此脚本完成(在上面的输入中使用GNU Awk进行测试):

#!/bin/bash

gawk -- '
    BEGIN {
        s = 0
        r = 0
    }

    /^Subset number/ {
        s = $4
        r = 0
    }

    /Type text/ {
        subset[s][r] = $5
        r++
    }

    END {
        for (s in subset) {
            subset_average[s] = 0
            for (r in subset[s]) {
                subset_average[s] += subset[s][r]
            }
            subset_average[s] /= length(subset[s])
        }
        print subset_average[2] - subset_average[1]
    }
'

通过修改END块,它也可以适应更多的子集。

如果“类型文本”只是示例中实际数据的替换,则数据行可以匹配。比如在一行的开头匹配数字,可能在空格之后。

答案 1 :(得分:2)

根据您的结构化文件,您可以更轻松地获取Y(m)列并对其进行求和。每个总和都存储在数组a中,其中键为Subset number

$ awk 'NR>1{for(i=1;i<=$9;i++)a[$2]+=$(23+i*10+i);a[$2]/=$9}END{print a[2]-a[1]"m"}' RS='Subset number' file
20m

对于两个子集,只需打印ENDa[1]-a[2]中两者之间的差异,即子集1的总和减去子集2的总和。对于更多子集,只需遍历每个键并执行所需的计算。