shell中多个文件的平均值

Kay*_*Kay 5 unix shell awk mean

我想计算15个文件的平均值: - ifile1.txt,ifile2.txt,.....,ifile15.txt.每个文件的列数和行数相同.部分数据看起来像

ifile1.txt      ifile2.txt       ifile3.txt
3  5  2  2 .    1  2  1  3 .    4  3  4  1 .
1  4  2  1 .    1  3  0  2 .    5  3  1  5 .
4  6  5  2 .    2  5  5  1 .    3  4  3  1 .
5  5  7  1 .    0  0  1  1 .    4  3  4  0 .
.  .  .  . .    .  .  .  . .    .  .  .  . .  
Run Code Online (Sandbox Code Playgroud)

我想查找一个新文件,它将显示这15个文件的平均值.

ofile.txt
2.66   3.33  2.33 2      . (i.e. average of 3 1 4, average of 5 2 3 and so on)
2.33   3.33  1    2.66   .
3      5     4.33 1.33   .
3      2.33  4    0.66   .
.      .     .    .      .
Run Code Online (Sandbox Code Playgroud)

我正在尝试跟随,但得到错误

awk'{for (i=1; i<=NF; i++)} rows=FNR;cols=NF} END 
{for (i=1; i<=rows; i++){for (j=1; j<=cols; j++) 
s+=$i;print $0,s/NF;s=0}}' ifile* > ofile.txt
Run Code Online (Sandbox Code Playgroud)

Jon*_*ler 5

正如所写:

awk'{for (i=1; i<=NF; i++)} rows=FNR;cols=NF} END
…
Run Code Online (Sandbox Code Playgroud)

你得到'command not found'作为错误,因为你必须awk在引号之间留一个空格和脚本.当你修复它时,你开始遇到问题,因为脚本的第一行有两个}且只有一个{.

当您解决问题时,您将需要一个2D数组,按行号和列号索引,对文件中的值求和.您还需要知道处理的文件数和列数.然后,您可以安排在END块中迭代2D数组.

awk 'FNR == 1 { nfiles++; ncols = NF }
     { for (i = 1; i < NF; i++) sum[FNR,i] += $i
       if (FNR > maxnr) maxnr = FNR
     }
     END {
         for (line = 1; line <= maxnr; line++)
         {
             for (col = 1; col < ncols; col++)
                  printf "  %f", sum[line,col]/nfiles;
             printf "\n"
         }
     }' ifile*.txt
Run Code Online (Sandbox Code Playgroud)

鉴于问题中的三个数据文件:

ifile1.txt

3 5 2 2
1 4 2 1
4 6 5 2
5 5 7 1
Run Code Online (Sandbox Code Playgroud)

ifile2.txt

1 2 1 3
1 3 0 2
2 5 5 1
0 0 1 1
Run Code Online (Sandbox Code Playgroud)

ifile3.txt

4 3 4 1
5 3 1 5
3 4 3 1
4 3 4 0
Run Code Online (Sandbox Code Playgroud)

我展示的脚本产生:

  2.666667  3.333333  2.333333
  2.333333  3.333333  1.000000
  3.000000  5.000000  4.333333
  3.000000  2.666667  4.000000
Run Code Online (Sandbox Code Playgroud)

如果要将小数位数控制为2,则使用%.2f代替%f.

  • 它不应该只是GNU`awk`的一个特性; 最后一个文件的最后一行的信息也可能在POSIX标准`awk`中提供.也就是说,我可能会加强代码以发现不正确的输入文件 - 列太多或太少,或者行太多或太少.我根本不信任用户,包括我自己,不要滥用系统.GIGO很好,但发现垃圾进来可以避免问题. (2认同)
  • 检查[`awk`]的POSIX规范(http://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html); 它明确表示FNR和NF都保留END块中最后一个文件的最后一行的值. (2认同)