在外壳的多个文件平均 [英] Average of multiple files in shell

查看:130
本文介绍了在外壳的多个文件平均的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要计算的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。
。 。 。 。 。 。 。 。 。 。 。 。 。 。 。

我想找到了一个新的文件,它会显示这15费尔的平均值。

  ofile.txt
2.66 3.33 2.33 2。 (即,3 1 4平均,平均5 2 3等)
2.33 3.33 2.66 1。
3 5 4.33 1.33。
3 2.33 0.66 4。
。 。 。 。 。

我与下列努力,但得到的错误

 的awk'{为(i = 1; I< = NF;我++)}行= FNR; COLS = NF} END
{为(i = 1; I< =行;我++){为(J = 1; J< = COLS; J ++)
S + = $ I;打印$ 0,S / NF,S = 0}}'IFILE *> ofile.txt


解决方案

由于写:

 的awk'{为(i = 1; I< = NF;我++)}行= FNR; COLS = NF} END
...

你'命令没有找到作为错误,因为你必须离开 AWK 之间以及引号中的脚本的空间。当你解决这个问题,你开始进入的问题,因为有两个} 且只有一个 {上的第一行该脚本。

当你避开标本兼治,你将需要一个二维数组,由行数和列编号编制索引,从文件中的值相加。您还需要了解处理的文件数和列数。然后,您可以安排在迭代在END块中的二维数组。

 的awk'FNR == 1 {NFILES ++; NCOLS = NF}
     {为(i = 1; I< NF;我++)总和[FNR,我] + = $ I
       如果(FNR> maxnr)maxnr = FNR
     }
     结束 {
         为(行= 1;线474 = maxnr;行++)
         {
             对于(COL = 1;山坳< NCOLS;西++)
                  printf的%F,总和[行,列] / NFILES;
             printf的\\ n
         }
     }IFILE * .TXT

这是问题由于三个数据文件:

ifile1.txt

  3 5 2 2
1 4 2 1
4 6 5 2
5 5 7 1

ifile2.txt

  1 2 1 3
1 3 0 2
2 5 5 1
0 0 1 1

ifile3.txt

  4 3 4 1
5 3 1 5
3 4 3 1
4 3 4 0

我发现这个脚本会产生:

  2.666667 3.333333 2.333333
  2.333333 3.333333 1.000000
  3.000000 5.000000 4.333333
  3.000000 2.666667 4.000000

如果你想控制的小数位的数量为2,然后用%。2F %F

I want to calculate the average of 15 files:- ifile1.txt, ifile2.txt, ....., ifile15.txt. Number of columns and rows of each file are same. Part of the data looks as

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 .
.  .  .  . .    .  .  .  . .    .  .  .  . .  

I would like to find over a new file which will show the average of these 15 fils.

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   .
.      .     .    .      .

I was trying with following, but getting error

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

解决方案

As written:

awk'{for (i=1; i<=NF; i++)} rows=FNR;cols=NF} END
…

you get 'command not found' as the error because you must leave a space between awk and the script inside the quotes. When you fix that, you start getting into problems because there are two } and only one { on the first line of the script.

When you get around to tackling the problem, you're going to need a 2D array, indexed by line number and column number, summing the values from the files. You'll also need to know the number of files processed, and the number of columns. You can then arrange to iterate over the 2D array in the END block.

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

Given the three data files from the question:

ifile1.txt

3 5 2 2
1 4 2 1
4 6 5 2
5 5 7 1

ifile2.txt

1 2 1 3
1 3 0 2
2 5 5 1
0 0 1 1

ifile3.txt

4 3 4 1
5 3 1 5
3 4 3 1
4 3 4 0

The script I showed produces:

  2.666667  3.333333  2.333333
  2.333333  3.333333  1.000000
  3.000000  5.000000  4.333333
  3.000000  2.666667  4.000000

If you want to control the number of decimal places to 2, then use %.2f in place of %f.

这篇关于在外壳的多个文件平均的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆