如何计算列中的n个值和总体平均值?

如何计算列中的n个值和总体平均值?

我真的很感谢一些帮助,因为我是 Linux 的相对新手。我正在使用grep,但我还想要所有提取的值的平均值(无论它们位于哪一列)以及从每个文件中提取的值(n)的数量(并放入每列中)。

命令:

grep -o "201[1-4].[0-9][ -9]" file1.txt file2.txt file3.txt \ | awk -F: '
  {
    if (!s[$1]){ s[$1]=$2 }
    else { s[$1]=s[$1]","$2 }
  }
  END {
    for (f in s){ print f","s[f] }
  }' | csvtool transpose -u " " - | column -nt

电流输出:

file1.txt  file3.txt  file2.txt
2013.17    2012.69    2013.54
2012.6     2013.44    2013.9
2013.12    2012.64    2013.66
2012.76    2013.11    2013.44
2013.75    2012.6     2013.89
2013.08    2012.41    2013.62
           2012.41    2013.41
           2013.2

总是有三列,但行数无法预测。

例子:

file1.txt  file3.txt  file2.txt
1          2          3
2          1          1
                      2

n=2        n=2        n=3                      
Average: 1.714

我正在使用的内容示例:

文件1:

2896.79 2897.65 2898.82 2012.69 2013.44 2897.4  2896.79 2012.64 2896.71 2217.4  2013.11 2012.6  2012.41 2012.41 2013.2  2897.12 2896.61 2896.35 2896.85 2896.26 2896.72
2913.91 2914.41 2914.27 2329.68 2329.71 2914.15 2914.32 2321.19 2914.02 2329.32 2896.49 2025.55 2328.84 2328.98 2329.1  2913.96 2913.48 2913.36 2913.97 2913.46 2913.71
2925.09 2925.58 2926.69 2401.39 2897.65 2925.77 2925.55 2328.96 2924.86 2897.19 2913.95 2029.61 2896.86 2896.93 2764.59 2925.18 2924.96 2924.68 2925.03 2924.18 2924.72
2933.54 2933.91 3196.19 2897.73 2914.79 3314.12 3016.04 2400.29 3015.62 2914.03 2925.09 2897.07 2913.69 2914.41 2897.38 2934.31 3058.51 3015.26 2934.32 2932.55 2933.38
2952.71 2953.49 3223.9  2914.91 2926.03 3321.3  3066.1  2896.71 3065.91 2925.14 2934.16 2914.04 2924.74 2925.54 2914.6  2952.92 3065.18 3065.74 2953.23 3072.91 2952.84
3016.02 3016.4  3249.51 2925.73 2932.82 3373.04 3073.91 2913.87 3073.65 2953.29 2952.94 2925.78 2952.15 2933.65 2925.67 3015.76 3073.21 3072.94 3065.81 3222.86 3015.45
3065.42 3059.27 3313.84 2953.72 2953.17 3444.15 3081.47 2925.02 3192.84 3015.73 3015.47 2953.12 3015.35 2953.29 2953.84 3073.71 3223.42 3080.34 3073.98 3312.09 3059.03

文件2:

2013.17 2012.6  2013.12 2036.82 2037.29 2036.53 2036.44 2032.6  2032.88 2012.76 2037.57 2037.26 2037.5  2042.89 2038.1  2013.75 2037.73 2038    2037.93 2033.5  2033.26 2013.08
2033.07 2033.03 2032.99 2042.08 2042.15 2042.14 2041.82 2036.84 2036.88 2033.27 2042.66 2042.65 2042.61 2461.68 2042.94 2037.45 2042.99 2042.96 2043.04 2037.29 2037.32 2033.44
2037.25 2037.27 2037.26 2080.15 2080.48 2080.35 2079.99 2042.18 2042.22 2037.31 2461.16 2080.81 2080.72 2465.94 2461.39 2043    2081.13 2081.08 2081.26 2042.62 2042.63 2037.55
2042.56 2042.49 2042.41 2464.77 2465.3  2465.08 2460.36 2053.03 2465.1  2042.58 2465.84 2461.76 2460.66 2473.93 2466.23 2461.58 2461.48 2461.6  2466.06 2053.48 2053.35 2042.68
2053.26 2053.42 2053.79 2480.18 2473.43 2472.84 2464.91 2080.37 2480.47 2058.27 2473.22 2465.78 2465.78 2482.02 2474.04 2466.07 2466.05 2466.01 2474.01 2080.88 2080.75 2053.24
2076.01 2059.33 2058.08 2500.19 2481.17 2480.7  2472.76 2460.1  2529.24 2076.3  2481.38 2473.76 2473.51 2501.38 2482.1  2473.97 2474.02 2473.99 2482.05 2276.73 2276.52 2058.42
2080.83 2075.97 2075.97 2529.14 2529.55 2529.28 2481.04 2465.12 2537.59 2080.44 2489.75 2481.63 2481.37 2525.17 2490.26 2482.1  2481.98 2481.96 2501.93 2465.52 2465.58 2076.22
2250.64 2080.54 2080.49 2537.07 2536.95 2537.65 2487.59 2473    2619.65 2276.27 2496.5  2500.38 2489.45 2530.2  2502.23 2525.03 2490.46 2501.06 2530.44 2500.93 2481.26 2080.85
2276.67 2118.71 2275.92 2635.42 2547.03 2544.73 2503.45 2480.94 2636.12 2465.35 2500.25 2524.95 2524.14 2538.07 2524.69 2530.47 2530.45 2524.9  2538.6  2529.88 2500.92 2276.34

文件3:

2207.2  2003.43 6628.01 2013.54 2013.9  2914.93 2003.72 3315.09 2013.66 2013.44 2147.76 2147.67 2207.45 2147.93 2013.89 2013.62 2008.56 2914.99 6632.04
2252.13 2036.51         2147.79 2036.93 2926.08 2013.41 5833.85 2037.51 2037.41 2206.79 2207.16 2898.47 2207.22 2037.11 2147.77 2037.9  3060    
2639.52 2120.66         2206.81 2147.77 3016.02 2036.57 6630.91 2147.94 2147.93 2914.59 2914.66 2915.5  2898.31 2207.46 2206.73 2147.96 3225.13 
2829.69 2147.96         2329.47 2207.1  3059.21 2147.81         2207.22 2207.15 3015.96 3058.98 2926.66 2915.11 2898.69 2329.31 2166.65 3314.22 
2914.74 2206.87         2897.84 2252.53 3225    2329.91         2329.35 2329.69 3031.21 3224.88 3059.82 2926.17 2915.3  2897.89 2207.42 5833.23 
3015.61 2252.38         2914.72 2329.72 3265.74 2897.86         2897.85 2897.81 3058.98 3265.62 3225.63 3059.46 2926.66 2914.67 2253.44 6034.36 
3030.72 2329.24         2925.98 2897.89 3305.35 2914.99         2915    2914.72 3077.57 3305.36 3266.57 3225.4  3016.03 2925.65 2330.06 6121.01

答案1

一步解决您的实际问题:

$ grep -o '201[1-4].[0-9]\+' file1.txt file2.txt file3.txt \
| datamash --sort -t: -g1 count 2 mean 2 

file1.txt:8:2012.8125
file2.txt:6:2013.08
file3.txt:7:2013.6371428571
  • grep从文件中获取值,
  • datamash按文件对项目进行计数并计算平均值。

现在每个文件只有一行:filename:n:average

更容易,对吧?

要获得所有文件的平均值,请删除分组:

grep -o '201[1-4].[0-9]\+' file1.txt file2.txt file3.txt \
| datamash --sort -t: mean 2

2013.1638095238

如果您需要打印精美的表格输出,请尝试以下操作:

$ cat mktable.sh
#!/bin/bash
myfiles="$@"

trap "rm ${myfiles//txt/txt.tempfile}" EXIT SIGTERM SIGINT

declare -A count

for f in $myfiles ; do
  # write the tempfile AND get the linecount simultaneously
    count[$f]="$(grep -o '201[1-4].[0-9]\+' "$f" | tee ${f}.tempfile | wc -l)"
  sed -i "1i $f" ${f}.tempfile        # write header
  sed -i "2i ---------" ${f}.tempfile # write header
done

( paste ${myfiles//txt/txt.tempfile} ;
 for item in $myfiles ; do echo -n '--------- '; done; echo
 for item in $myfiles ; do echo -n "n=${count[$item]} " ; done ; echo ;
 for item in $myfiles ; do echo -n '--------- '; done; echo
 )\
  | column -nt

echo "Average: $(grep -o '201[1-4].[0-9]\+' $myfiles | datamash -s -t: mean 2)"

$ ./mktable.sh file*.txt
file1.txt  file2.txt  file3.txt
---------  ---------  ---------
2012.69    2013.17    2013.54
2013.44    2012.6     2013.9
2012.64    2013.12    2013.66
2013.11    2012.76    2013.44
2012.6     2013.75    2013.89
2012.41    2013.08    2013.62
2012.41               2013.41
2013.2                
---------  ---------  ---------  
n=8        n=6        n=7        
---------  ---------  ---------  
Average: 2013.1638095238

答案2

我将使用 AWK 处理整个事情:

#!/usr/bin/gawk -f

BEGIN {
    RS = " +|\t+|\n"
    OFS = "\t"
}

$1 >= 2011 && $1 < 2015 {
    counts[FILENAME]++
    allcounts++
    allsum += $1
    values[FILENAME][length(values[FILENAME])] = $1
}

END {
    for (file in counts) {
        printf "%s%s", file, OFS
        if (counts[file] > maxlength) {
            maxlength = counts[file]
        }
    }
    printf "\n"
    for (i = 0; i < maxlength; i++) {
        for (file in counts) {
            if (i < counts[file]) {
                printf "%.2f", values[file][i]
            }
            printf "%s", OFS
        }
        printf "\n"
    }
    printf "\n"
    for (file in counts) {
        printf "n=%d%s", counts[file], OFS
    }
    printf "\n"
    printf "Average: %f\n", allsum / allcounts
}

将其保存到文件(例如546830),使其可执行(chmod 755 546830),然后按如下方式运行:

./546830 file1.txt file2.txt file3.txt

您可以使用以下命令将列对齐column

./546830 file1.txt file2.txt file3.txt | column -t

使用你的问题中给出的例子,我得到

file1.txt  file3.txt    file2.txt
2012.69    2013.54      2013.17
2013.44    2013.90      2012.60
2012.64    2013.66      2013.12
2013.11    2013.44      2012.76
2012.60    2013.89      2013.75
2012.41    2013.62      2013.08
2012.41    2013.41      
2013.20                 
n=8        n=7          n=6
Average:   2013.163810  

输出中文件的顺序不一定与输入中的顺序匹配,但值不会混淆。如果顺序很重要,我可以更改脚本以保留它。

其工作方式是将每个文件分成空格和换行符上的记录,然后将符合条件(包括 2011 年至 2015 年除外)的每个记录存储在数组中values,并按文件名和计数进行索引。这些值也会添加到allsum累加器中,每个文件的计数保存在数组中counts,聚合计数保存在allcounts累加器中。

相关内容