Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Awk 计算文本文件中列的平均值_Awk - Fatal编程技术网

Awk 计算文本文件中列的平均值

Awk 计算文本文件中列的平均值,awk,Awk,我有两个名为f1和f2的文件夹。这些文件夹包含300个包含两列的文本文件。文件内容如下所示。我想计算第二列的平均值。两个文件夹中的文件名相同 file1 in f1 folder 54 6 55 10 57 5 file2 in f1 folder 24 8 28 12 file1 in f2 folder 34 3 22 8 file2 in f2 folder 24 8 28 13 输出 folder1 folder2

我有两个名为f1和f2的文件夹。这些文件夹包含300个包含两列的文本文件。文件内容如下所示。我想计算第二列的平均值。两个文件夹中的文件名相同

file1 in f1 folder
54  6
55 10
57 5

file2 in f1 folder
24  8
28  12

file1 in f2 folder
34 3
22 8

file2 in f2 folder
24  8
28  13
输出

                   folder1       folder2

     file1         21/3= 7       11/2=5.5
     file2         20/2=10       21/2=10.5

      --            --             --    

      --            --             --

    file300         --             --

              total mean of folder1 = sum of the means/3oo
              total mean of folder2 = sum of the means/3oo

我会用两个
awk
脚本来完成。(最初,我在中间有一个<代码>排序/代码>阶段,但实际上这不是必要的。然而,我认为两个脚本可能比把它们组合成一个脚本更容易。如果其他人把它全部放在一起,它是可以理解的,那么选择他们的解决方案。” 运行和输出示例 这是基于问题中显示的4个文件。文件名列在命令行上,但顺序无关紧要。代码假定文件名中只有一个斜杠,文件名中没有空格等

$ awk -f summary1.awk f?/* | awk -f summary2.awk
file1                      21/3   =      7.000       11/2   =      5.500
file2                      20/2   =     10.000       21/2   =     10.500
total mean of f1     =     17/2   =      8.500
total mean of f2     =     16/2   =      8.000
总结1.awk 这将依次处理每个文件,对第2列中的值求和并计算行数。它打印出文件夹名、文件名、总数和计数

总结2.awk
{
总和[$2,$1]=$3
cnt[$2,$1]=$4
如果(文件[$2]++==0)文件列表[n1++]=$2
如果(折叠[$1]++==0)折叠列表[n2++]=$1
}
结束{for(i=0;i
文件
关联数组跟踪对文件名的引用。
file\u列表
数组按读取顺序保存文件名。类似地,
折叠
关联数组跟踪文件夹名称,
折叠列表
数组按文件夹名称的出现顺序跟踪文件夹名称。如果对第一个命令提供名称的顺序做了一些奇怪的事情,则可能需要在两个
awk
命令之间插入
sort
命令,例如
sort-k2,2-k1,1

sum
关联数组包含给定文件名和文件夹名的总和。
cnt
关联数组包含给定文件名和文件夹名的计数

报告的
END
部分有两个主循环(尽管第一个循环包含嵌套循环)。第一个主循环按照显示的顺序处理文件,为每个文件夹生成一行,其中包含一个条目。它还累积文件夹名称的平均值。
第二个主循环为每个文件夹生成“total mean”数据。我不确定统计数据是否有意义(folder1的总体平均值不应该是folder1中的值之和除以条目数,或者41/5=8.2,而不是17/2或8.5?),但计算结果符合我认为问题的要求(平均值之和/文件数,在问题中写为300).

在grep的帮助下:

grep '[0-9]' folder[12]/* | awk '
    {
       split($0,b,":"); 
       f=b[1]; split(f,c,"/"); d=c[1]; f=c[2]; 
       s[f][d]+=$2; n[f][d]++; nn[d]++;} 
    END{ 
      for (f in s) {
        printf("%-10s", f);
        for (d in s[f]) {
          a=s[f][d] / n[f][d];
          printf(" %6.2f ", a);
          p[d] += a;
        }
        printf("\n");
      }  
      for (d in p) { 
        printf("total mean %-8s = %8.2f\n", d, p[d]/nn[d]);
      }
    }'

folder1中是否有任何文件未出现在folder2中,反之亦然?您看到在命令行上传递了哪些参数?谢谢您的详细回答。folder1和folder2中的文件数相同。。我会在几个小时内根据我的需要检查这一点,然后接受你的回答。好的,但请注意,如果你有文件
f1/n1
f1/n2
f2/n1
f2/n3
,两个文件夹中的文件数量相同,但
f1
中有一个文件(即
n2
),而
f2
中没有对应的文件,以及
f2
(即
n3
)中的文件,在
f1
中没有对应文件。所以我问了一个比“文件数是否相同”更强的条件。但是,如果其中一个文件中存在一个与另一个文件丢失的文件,则代码将爆炸性地出现被零除的错误。这样的失败是可以证明的,但你说过这不会发生。(我的答案代码也适用于3个目录。)@leffler所有文件夹中的文件数量和名称都相同。我可以将此代码用于三个以上的目录吗?我试过像这样的awk-f summary1.awk f1/*.txt,f2/*.txt,f3/*.txt,f4/*.txt,f5/*.txt | awk-f summary2.awk。但我得到了错误。awk:无法打开f1/*.txt、f2/*.txt、f3/*.txt、f4/*.txt、f5/*.txt(没有这样的文件或目录)。我想改变你写的总平均数的公式。这是一个错误。代码不限于2或3个目录;它名义上将处理5个甚至50个目录。输出格式将非常广泛,但这是一个表象问题,而不是计算问题。命令行上的问题源于使用逗号而不是空格来分隔文件名:
awk-f summary1.awk f1/*.txt f2/*.txt f3/*.txt f4/*.txt f5/*.txt | awk-f summary2.awk
应该可以工作。
    {
        sum[$2,$1] = $3
        cnt[$2,$1] = $4
        if (file[$2]++ == 0) file_list[n1++] = $2
        if (fold[$1]++ == 0) fold_list[n2++] = $1
    }
END {   for (i = 0; i < n1; i++)
        { 
            printf("%-20s", file_list[i])
            name = file_list[i]
            for (j = 0; j < n2; j++)
            {
                folder = fold_list[j]
                s = sum[name,folder]
                n = cnt[name,folder]
                a = (s + 0.0) / n
                printf("   %6d/%-3d = %10.3f", s, n, a)
                gsum[folder] += a
            }
            printf("\n")
        }
        for (i = 0; i < n2; i++)
        {
            folder = fold_list[i]
            s = gsum[folder]
            n = n1;
            a = (s + 0.0) / n
            printf("total mean of %-6s = %6d/%-3d = %10.3f\n", folder, s, n, a)
        }
    }
grep '[0-9]' folder[12]/* | awk '
    {
       split($0,b,":"); 
       f=b[1]; split(f,c,"/"); d=c[1]; f=c[2]; 
       s[f][d]+=$2; n[f][d]++; nn[d]++;} 
    END{ 
      for (f in s) {
        printf("%-10s", f);
        for (d in s[f]) {
          a=s[f][d] / n[f][d];
          printf(" %6.2f ", a);
          p[d] += a;
        }
        printf("\n");
      }  
      for (d in p) { 
        printf("total mean %-8s = %8.2f\n", d, p[d]/nn[d]);
      }
    }'